1. 基础篇
1.1 Nginx介绍
Nginx是一款轻量级的Web服务器、反向代理服务器,是由俄罗斯的程序设计师Igor Sysoev所开发,使用C语言开发。由于其内存占用少,启动速度极快,具有高并发处理能力,在互联网项目中被广泛应用。
1.1.1 主要特点
- 内存占用少,并发能力强
- 高度模块化的设计,具有很好的扩展性
- 高可靠性和稳定性
- 支持热部署,不停机更新配置和程序版本
1.1.2 核心功能
- HTTP服务器(静态资源服务器)
- 反向代理服务器
- 负载均衡
- 邮件代理服务器
- 支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能
- 支持第三方模块扩展
目前,Nginx在全球网站中的市场份额超过33.5%,位居第二,仅次于Apache。其优秀的性能和丰富的功能使其成为现代Web架构中不可或缺的组件。
1.2 Nginx下载安装
1.2.1 版本选择
- Mainline version:开发版,包含新功能和修复
- Stable version:稳定版,建议生产环境使用
- Legacy versions:老版本
1.2.2 安装方式
- 包管理器安装(推荐)
# CentOS/RHEL
yum install nginx
# Ubuntu/Debian
apt-get install nginx
- 源码编译安装
# 下载源码
wget http://nginx.org/download/nginx-1.20.1.tar.gz
# 解压
tar -zxvf nginx-1.20.1.tar.gz
# 配置、编译、安装
./configure
make
make install
- Docker容器化部署(推荐生产环境)
# 拉取nginx镜像
docker pull nginx
# 创建挂载目录
mkdir -p /usr/local/docker-volumes/nginx/{conf,log,html,cert}
# 运行临时容器并复制配置
docker run --name nginx -d -p 80:80 nginx
docker cp nginx:/etc/nginx/nginx.conf /usr/local/docker-volumes/nginx/
docker cp nginx:/etc/nginx/conf.d /usr/local/docker-volumes/nginx/
docker cp nginx:/usr/share/nginx/html /usr/local/docker-volumes/nginx/
docker rm -f nginx
# 启动正式容器
docker run --name nginx -m 200m -p 80:80 -p 443:443 \
-v /usr/local/docker-volumes/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /usr/local/docker-volumes/nginx/conf.d:/etc/nginx/conf.d \
-v /usr/local/docker-volumes/nginx/cert:/etc/nginx/cert \
-v /usr/local/docker-volumes/nginx/html:/usr/share/nginx/html \
-v /usr/local/docker-volumes/nginx/log:/var/log/nginx \
-e TZ=Asia/Shanghai \
--restart=always \
--network host \
--privileged=true -d nginx
1.3 Nginx基本命令和配置
1.3.1 常用命令
# 强制关闭Nginx,可能不保存相关信息
nginx -s stop
# 平稳关闭Nginx,保存相关信息
nginx -s quit
# 重新加载配置
nginx -s reload
# 重新打开日志文件
nginx -s reopen
# 指定配置文件
nginx -c filename
# 测试配置文件语法
nginx -t
# 显示版本信息
nginx -v
# 显示详细版本信息
nginx -V
1.3.2 配置文件结构
Nginx配置文件主要由以下6个部分组成:
- main:用于进行nginx全局信息的配置
- events:用于nginx工作模式的配置
- http:用于进行http协议信息的一些配置
- server:用于进行服务器访问信息的配置
- location:用于进行访问路由的配置
- upstream:用于进行负载均衡的配置
整体结构如下:
# 全局配置块:影响nginx全局的配置
main {
worker_processes 4; # 工作进程数,通常设置为CPU核心数
worker_connections 1024; # 每个工作进程的最大连接数
}
# 事件块:配置影响nginx服务器或与用户的网络连接
events {
use epoll; # 事件驱动模型,Linux系统推荐使用epoll
worker_connections 1024; # 每个工作进程的最大连接数
}
# HTTP块:配置代理、缓存、日志等绝大多数功能
http {
# 基础配置
include mime.types; # 文件扩展名与文件类型映射表
default_type application/octet-stream; # 默认文件类型
# 服务器块:配置虚拟主机的相关参数
server {
listen 80; # 监听端口
server_name example.com; # 服务器名称
# location块:配置请求的路由和页面处理
location / {
root /usr/share/nginx/html; # 根目录
index index.html; # 默认页面
}
location /api/ {
proxy_pass http://backend; # 反向代理配置
}
}
# upstream块:配置负载均衡服务器组
upstream backend {
server 127.0.0.1:8001 weight=3; # 权重为3
server 127.0.0.1:8002 weight=2; # 权重为2
}
}
1.3.3 Location匹配规则
location [ = | ~ | ~* | ^~ ] url {
# 配置内容
}
匹配修饰符说明:
- =:精确匹配,要求请求的URL与配置的URL完全相同
- ^~:前缀匹配,不检查正则表达式**
- ~:区分大小写的正则匹配**
- ~:不区分大小写的正则匹配
- /:通用匹配,所有请求都会匹配到
匹配优先级(从高到低):
- = 精确匹配
- ^~ 前缀匹配
- ~ 和 ~正则匹配
- / 通用匹配
配置示例:
# 精确匹配
location = /api {
# 只匹配 /api 请求
}
# 前缀匹配
location ^~ /static/ {
# 匹配所有以 /static/ 开头的请求
root /usr/share/nginx/html;
}
# 正则匹配(区分大小写)
location ~ \.(gif|jpg|png)$ {
# 匹配以 .gif、.jpg、.png 结尾的请求
}
# 正则匹配(不区分大小写)
location ~* \.(js|css)$ {
# 匹配以 .js、.css 结尾的请求
}
# 通用匹配
location / {
# 匹配所有请求
root /usr/share/nginx/html;
index index.html;
}
注意事项:
- 多个location配置的情况下,匹配顺序优先级很重要
- 正则表达式中如果包含字符
^~
,不要误认为是前缀匹配 - 如果正则表达式与前缀字符串都可以匹配,按照优先级采用第一个匹配的规则
root:用于指定访问根目录时,访问虚拟主机的web目录
index:在不指定访问具体资源时,默认展示的资源文件列表
1.4 Nginx核心功能与实际应用
1.4.1 静态资源服务
Nginx作为静态资源服务器的性能远优于Tomcat等应用服务器。它可以高效处理如HTML、CSS、JavaScript、图片、视频等静态资源。
配置示例:
server {
listen 80; # 监听80端口
server_name example.com; # 服务器域名
charset utf-8; # 设置编码
# 静态文件配置
location / {
root /usr/share/nginx/html; # 静态文件根目录
index index.html index.htm; # 默认首页
expires 30d; # 静态文件缓存30天
add_header Cache-Control "public, no-transform";
}
# 针对不同类型文件的处理
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
root /usr/share/nginx/html; # 媒体文件目录
expires 7d; # 缓存7天
access_log off; # 关闭访问日志
}
}
1.4.2 反向代理
反向代理就是隐藏真实的服务器地址,保护真实的服务器,用户在访问时访问的是代理服务器。
nginx 中常见的反向代理指令有两个:proxy_pass 和 fastcgi_pass,前者使用标准的 HTTP 协议转发,后者使用 FastCGI 协议转发。这里我们以 proxy_pass 为例来做介绍。
proxy_pass 有两种配置写法:
- **直接指向要代理的地址,可以是一台具体的主机(ip),也可以是一个具体的网址 **
# 简单反向代理
server {
listen 80;
server_name example.com;
# 代理到单一服务器
location /api/ {
proxy_pass http://backend:8080/; # 后端服务地址
# 设置代理请求头
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
- 可以搭配负载均衡指向一组服务器(参考负载均衡)
# 负载均衡反向代理
upstream backend_servers {
server 192.168.1.10:8080 weight=3; # 权重为3
server 192.168.1.11:8080 weight=2; # 权重为2
keepalive 32; # 保持连接数
}
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://backend_servers;
proxy_http_version 1.1; # 使用HTTP/1.1
proxy_set_header Connection ""; # 启用keepalive
}
}
代理配置说明:
- proxy_pass:指定后端服务器地址
- proxy_set_header:设置代理请求头信息
- proxy_connect_timeout:与后端服务器连接超时时间
- proxy_send_timeout:发送请求给后端服务器超时时间
- proxy_read_timeout:从后端服务器读取响应超时时间
1.4.3 负载均衡
负载均衡是Nginx的核心功能之一,负载均衡是解决高并发、海量数据问题的常用手段。Nginx提供了多种负载均衡策略,通过反向代理实现请求分发,解决单点服务器性能瓶颈问题,可以根据实际需求选择合适的方案。
1.4.3.1 基础配置
# 定义后端服务器组
upstream backend {
server 192.168.1.10:8080 weight=3; # 权重为3
server 192.168.1.11:8080 weight=2; # 权重为2
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend; # 代理到服务器组
}
}
1.4.3.2 负载均衡策略
- 轮询(默认)
默认方式,按时间顺序逐一分配到不同的后端服务器
upstream backend {
server 192.168.1.10:8080; # 轮询方式平均分配请求
server 192.168.1.11:8080;
}
- 加权轮询
weight值越大,分配到的访问机率越高
upstream backend {
server 192.168.1.10:8080 weight=3; # 访问比例为3
server 192.168.1.11:8080 weight=2; # 访问比例为2
}
- IP哈希
根据客户端IP分配,可用于会话保持
upstream backend {
ip_hash; # 启用IP哈希
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
- 最少连接
优先分配给连接数最少的服务器
upstream backend {
least_conn; # 优先分配给连接数最少的服务器
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
- 备份服务器
当主服务器不可用时才会启用的备份服务器
upstream backend {
server 192.168.1.10:8080; # 主服务器
server 192.168.1.11:8080 backup; # 备份服务器
}
高级配置参数:
upstream backend {
server 192.168.1.10:8080 weight=3 max_fails=3 fail_timeout=30s; # 健康检查
server 192.168.1.11:8080 weight=2 max_conns=1000; # 连接数限制
keepalive 32; # 保持连接数
}
参数说明:
- max_fails:允许请求失败的次数
- fail_timeout:经过max_fails失败后,服务暂停的时间
- max_conns:最大并发连接数
- keepalive:保持的空闲连接数
1.4.4 限流配置
Nginx限流是限制用户请求速度的重要机制,用于防止服务器过载。Nginx的限流基于漏桶算法实现,主要包括以下三种:
1.4.4.1 正常限制访问频率
# 限制每个IP每秒只能发送1个请求
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
location /api/ {
limit_req zone=one;
proxy_pass http://backend;
}
}
1.4.4.2 突发限制访问频率
# 允许突发流量,但超过设定值后排队处理
limit_req_zone $binary_remote_addr zone=two:10m rate=1r/s;
server {
location /api/ {
limit_req zone=two burst=5 nodelay;
proxy_pass http://backend;
}
}
1.4.4.3 限制并发连接数
# 限制每个IP最多保持3个并发连接
limit_conn_zone $binary_remote_addr zone=three:10m;
server {
location /download/ {
limit_conn three 3;
proxy_pass http://backend;
}
}
2. 进阶篇
2.1 性能优化
2.1.1 Gzip压缩
以下配置需要添加在 http 块中,用于全局启用和配置Gzip压缩:
# 启用Gzip压缩 - http块配置
gzip on; # 启用Gzip压缩功能
gzip_min_length 1k; # 小于1k的文件不压缩,避免压缩很小的文件
gzip_comp_level 6; # 压缩级别1-9,级别越高压缩率越大但CPU消耗也越高
gzip_types text/plain text/css text/javascript application/json application/javascript application/xml; # 指定需要压缩的MIME类型
gzip_vary on; # 添加Vary: Accept-Encoding响应头,用于CDN缓存
gzip_proxied any; # 对所有代理请求进行压缩
2.1.2 缓存配置
以下配置需要添加在 server 块中的 location 块内,用于配置静态资源的浏览器缓存:
# 静态资源缓存 - server块中的location配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d; # 设置浏览器缓存过期时间为30天
add_header Cache-Control "public, no-transform"; # 允许公共缓存,禁止转换
access_log off; # 关闭访问日志以提高性能
}
2.1.4 连接优化
以下配置需要添加在 http 块中,用于优化客户端连接参数:
# 连接超时设置 - http块配置
keepalive_timeout 65; # 保持长连接的超时时间,单位秒
keepalive_requests 100; # 单个长连接最大请求数
client_body_timeout 10; # 读取请求体的超时时间,单位秒
client_header_timeout 10; # 读取请求头的超时时间,单位秒
send_timeout 10; # 向客户端发送响应的超时时间,单位秒
2.2 HTTPS和HTTP/2配置
2.2.1 基础HTTPS配置
以下配置需要添加在 http 块中,包含两个 server 块配置,用于实现HTTP到HTTPS的重定向和HTTPS服务器的安全配置:
# HTTP重定向到HTTPS - http块中的第一个server配置
server {
listen 80; # 监听80端口
server_name example.com; # 域名配置
return 301 https://$server_name$request_uri; # 将所有HTTP请求永久重定向到HTTPS
}
# HTTPS服务器配置 - http块中的第二个server配置
server {
listen 443 ssl http2; # 监听443端口并启用SSL和HTTP/2
server_name example.com; # 域名配置
# SSL证书配置 - 在server块中配置SSL证书路径
ssl_certificate /etc/nginx/cert/example.com.pem; # SSL证书公钥
ssl_certificate_key /etc/nginx/cert/example.com.key; # SSL证书私钥
# SSL协议和加密套件配置 - 增强HTTPS安全性
ssl_protocols TLSv1.2 TLSv1.4; # 只允许TLS 1.2和1.4,禁用不安全的协议
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; # 配置加密算法
ssl_prefer_server_ciphers on; # 优先使用服务器的加密套件配置
# SSL会话缓存 - 优化SSL握手性能
ssl_session_cache shared:SSL:10m; # 配置10MB的共享会话缓存
ssl_session_timeout 10m; # 设置SSL会话缓存超时时间
# HSTS配置 - 强制客户端使用HTTPS
add_header Strict-Transport-Security "max-age=31536000"; # 启用HSTS,有效期一年
}
2.2.2 HTTP/2优化
以下配置需要添加在 http 块或 server 块中,用于优化HTTP/2性能:
# HTTP/2特定优化 - http块或server块配置
http2_push_preload on; # 启用服务器推送,支持preload资源预加载
http2_max_concurrent_streams 128; # 限制每个连接的最大并发流数量
http2_idle_timeout 3m; # 设置空闲连接的超时时间为3分钟
2.3 安全加固
2.3.1 DDoS防护
以下配置包含多个层次的DDoS防护措施:
# IP连接限制 - http块配置
limit_conn_zone $binary_remote_addr zone=addr:10m; # 在http块中定义共享内存区,用于存储IP连接计数
limit_conn addr 100; # 在http块或server块中限制每个IP的并发连接数
# 请求频率限制 - http块和location块配置
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; # 在http块中定义请求限制区,限制每秒请求数
location / {
limit_req zone=req_limit burst=20 nodelay; # 在location块中配置请求限制,允许短时突发20个请求
}
# TCP洪水攻击防护 - server块配置
server {
listen 80 backlog=65535; # 设置等待连接队列大小,防止TCP SYN洪水攻击
listen 443 ssl http2 backlog=65535; # SSL端口同样设置较大的等待队列
}
2.3.2 访问控制
以下配置展示了多种访问控制方式,可以添加在 server 块中:
# 禁止特定User-Agent - server块配置
if ($http_user_agent ~* (Scrapy|Curl|WebBench)) {
return 403; # 检测到爬虫等工具时返回禁止访问
}
# IP访问控制 - server块中的location配置
location /admin/ {
allow 192.168.1.0/24; # 允许特定IP段访问管理界面
deny all; # 禁止其他所有IP访问
}
# 防盗链配置 - server块中的location配置
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked server_names *.example.com; # 设置允许的来源域名
if ($invalid_referer) {
return 403; # 对于非法引用的请求返回禁止访问
}
}
2.4 日志管理
2.4.1 访问日志
以下配置需要添加在 http 块中,用于定义日志格式和配置访问日志:
# 日志配置 - http块配置
http {
# 定义主日志格式,包含客户端IP、访问时间、请求信息等
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 配置访问日志
access_log /var/log/nginx/access.log main buffer=32k flush=5s; # 启用主日志格式,使用32k缓冲,每5秒刷新
access_log /var/log/nginx/access_json.log json buffer=32k; # 启用JSON格式日志,便于日志分析
}
2.4.2 错误日志
以下配置可以添加在 main 块、http 块、server 块或 location 块中,用于配置错误日志:
# 错误日志配置 - 可在main、http、server或location块中配置
error_log /var/log/nginx/error.log warn; # 设置错误日志级别为warn
# 可选的错误日志级别(从详细到简略)
# error_log /var/log/nginx/error.log debug; # 调试级别:输出所有调试信息
# error_log /var/log/nginx/error.log info; # 信息级别:输出有用的信息
# error_log /var/log/nginx/error.log notice; # 通知级别:输出普通但重要的信息
# error_log /var/log/nginx/error.log warn; # 警告级别:输出警告信息
# error_log /var/log/nginx/error.log error; # 错误级别:输出错误信息
# error_log /var/log/nginx/error.log crit; # 严重错误级别:输出严重错误信息
2.4.3 日志轮转
# 日志轮转配置(logrotate)
/var/log/nginx/*.log {
daily # 每天轮转
missingok # 忽略丢失的日志文件
rotate 52 # 保留52个备份
compress # 压缩轮转后的日志
delaycompress # 延迟压缩到下一次轮转
notifempty # 空文件不轮转
create 640 nginx adm # 创建新日志文件的权限和所有者
sharedscripts # 所有日志共用一个脚本
postrotate
# 重新打开日志文件
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
2.5 监控和调试
2.5.1 状态监控
以下配置需要添加在 server 块中的 location 块内,用于配置Nginx状态监控页面:
# 状态监控配置 - server块中的location配置
location /nginx_status {
stub_status on; # 启用状态页,显示连接数等统计信息
access_log off; # 关闭访问日志,减少磁盘IO
allow 127.0.0.1; # 只允许本地IP访问,提高安全性
deny all; # 拒绝其他所有IP访问
}
2.5.2 调试配置
以下配置包含两部分:
- 调试日志配置(可添加在 main 块、http 块、server 块或 location 块中)
- 调试信息配置(需要添加在 server 块中的 location 块内)
# 调试日志配置 - 可在main、http、server或location块中配置
error_log /var/log/nginx/debug.log debug; # 启用调试级别的日志记录
# 调试信息配置 - server块中的location配置
location /debug/ {
add_header X-Debug-Message $request_uri; # 在响应头中添加当前请求的URI
add_header X-Server-Name $hostname; # 在响应头中添加服务器主机名
add_header X-Request-ID $request_id; # 在响应头中添加唯一请求ID
}
3. 最佳实践
3.1 性能优化建议
- 合理使用缓存
以下配置需要添加在 http 块中,用于优化文件缓存:
# 文件缓存配置 - http块配置
open_file_cache max=1000 inactive=20s; # 最多缓存1000个文件,20秒内未被访问则清除
open_file_cache_valid 30s; # 每30秒检查一次缓存的有效性
open_file_cache_min_uses 2; # 文件被访问2次后才会被缓存
open_file_cache_errors on; # 缓存文件找不到等错误信息
- 优化工作进程
以下配置需要添加在 main 块中,用于优化Nginx工作进程:
# 工作进程配置 - main块配置
worker_processes auto; # 自动设置工作进程数为CPU核心数
worker_cpu_affinity auto; # 自动绑定工作进程到CPU核心
# 进程优先级配置
worker_priority -5; # 提高工作进程优先级(-20到19,值越小优先级越高)
- 优化事件模型
以下配置需要添加在 events 块中,用于优化连接处理:
# 事件模型配置 - events块配置
events {
use epoll; # 使用epoll事件模型,提高并发处理能力
worker_connections 10240; # 每个工作进程同时处理的最大连接数
multi_accept on; # 允许同时接受多个新连接
}
3.2 安全最佳实践
- 隐藏版本信息
以下配置需要添加在 http 块中,用于隐藏Nginx版本信息:
# 版本信息配置 - http块配置
server_tokens off; # 在错误页面和响应头中隐藏Nginx版本号
- 配置安全响应头
以下配置需要添加在 http 块或 server 块中,用于增强安全性:
# 安全响应头配置 - http块或server块配置
add_header X-Frame-Options "SAMEORIGIN"; # 防止网站被嵌入恶意iframe中
add_header X-XSS-Protection "1; mode=block"; # 启用浏览器XSS防护
add_header X-Content-Type-Options "nosniff"; # 禁止浏览器猜测内容类型
add_header Content-Security-Policy "default-src 'self'"; # 限制资源只能从本站加载
- 限制上传文件大小
以下配置需要添加在 http 块、server 块或 location 块中,用于限制上传文件大小:
# 上传限制配置 - http块、server块或location块配置
client_max_body_size 10m; # 限制客户端请求体大小为10MB