核心模块与常见指令详解
深入 Nginx 的指令层,是配置落地的关键。下面按功能模块拆解,每个指令都说明含义、语法、典型示例,并点出极易踩坑的地方。
一、核心功能模块
这些指令直接决定了 Nginx 的整体行为与性能。
| 指令 | 上下文 | 含义 | 示例 |
|---|---|---|---|
user | main | Worker 进程的运行用户,影响读写权限。建议用低权限用户(如 www-data)。 | user www-data; |
worker_processes | main | Worker 进程数,推荐 auto 自动匹配 CPU 核心数;也支持指定数字。 | worker_processes auto; |
worker_connections | events | 每个 Worker 可同时打开的最大连接数。实际最大并发 = worker_processes * worker_connections (减去代理等占用)。需配合系统文件描述符限制 (ulimit -n)。 | events { worker_connections 2048; } |
error_log | 多种 | 错误日志路径与级别(debug, info, notice, warn, error, crit)。多上下文可用。 | error_log /var/log/nginx/error.log warn; |
sendfile | http, server, location | 开启零拷贝文件传输,直接在内核空间复制数据,大幅提升静态文件性能。 | sendfile on; |
tcp_nopush | http, server, location | 在 sendfile on 时有效,将响应头和数据包合并发送,减少网络包数量,提高效率。 | tcp_nopush on; |
keepalive_timeout | http, server, location | 长连接超时时间。第一个参数是服务器端保持超时,第二个(可选)是设置响应头 Keep-Alive: timeout= 的值,告知客户端超时。 | keepalive_timeout 65 65; |
优化建议:sendfile on; tcp_nopush on; 搭配使用,对于静态文件服务极为有效。keepalive_timeout 不宜太长,避免闲置连接占用资源。
二、location 匹配规则(重中之重)
location 决定了请求最终由哪个块处理,规则精微,必须牢记优先级。
1. 匹配语法
| 匹配符 | 示例 | 含义 |
|---|---|---|
= | = /admin | 精确匹配,路径必须完全相等。优先级最高。 |
^~ | ^~ /images/ | 前缀优先,匹配前缀后不再检查正则表达式。 |
~ | ~ \.php$ | 正则匹配,区分大小写。 |
~* | ~* \.jpg$ | 正则匹配,不区分大小写。 |
| (无符号) | / 或 /static | 普通前缀匹配,匹配路径的前缀部分。 |
2. 优先级顺序(非常重要)
Nginx 会按照以下顺序选择最终的 location:
- 先遍历所有精确匹配
=,命中后立即停止,直接使用。 - 再遍历所有前缀匹配(含
^~和普通前缀),找到最长命中。- 如果这个最长前缀带
^~修饰符,则立即使用,不再检查正则。
- 如果这个最长前缀带
- 按配置文件中出现的顺序依次检查正则表达式(
~和~*),第一个匹配的正则被使用。 - 若没有正则匹配,则使用第2步找到的最长前缀匹配。
流程图简示:
请求进入 ─→ 是否有精确匹配(=)? ──YES→ 使用该 location
│NO
▼
找出最长前缀匹配(包括^~及无符号)
│
是否带 ^~ 修饰? ──YES→ 使用该 location(忽略正则)
│NO
▼
按出现顺序匹配正则(~ 和 ~*)
│
有命中? ──YES→ 使用第一个命中的正则 location
│NO
▼
使用之前找到的最长前缀匹配(无^~)
经典例子:
location = / { return 200 "exact /"; }
location / { return 200 "prefix /"; }
location /documents/ { return 200 "prefix /documents/"; }
location ^~ /images/ { return 200 "prefix ^~ images"; }
location ~ \.(gif|jpg)$ { return 200 "regex images"; }
- 请求
/:命中精确=。 - 请求
/index.html:最长前缀是/,然后正则都不匹配,最终使用/。 - 请求
/images/logo.jpg:最长前缀是^~ /images/,因为有^~直接使用,不会尝试正则。 - 请求
/documents/report.pdf:最长前缀/documents/,无^~,接着检查正则,不匹配,使用/documents/。 - 请求
/photo.jpg:最长前缀是/,继续检查正则,匹配~ \.(gif|jpg)$,使用该正则 location。
三、静态资源服务
处理静态文件是 Nginx 的拿手好戏,但有几个易混淆点必须厘清。
1. root 与 alias 的区别(极易混淆)
root:将请求 URI 附加在指定的文件系统路径之后。alias:将匹配到的路径替换为指定路径,URI 尾部不会追加。
| 指令 | 配置示例 | 请求 URI | 实际查找的文件路径 |
|---|---|---|---|
root | location /images/ { root /data; } | /images/cat.png | /data/images/cat.png |
alias | location /images/ { alias /data; } | /images/cat.png | /data/cat.png |
关键点:alias 后面的路径直接对应匹配的 location 部分,末尾的 / 必须一致。若 location 后带有斜杠,alias 后面也建议带斜杠,否则可能出现路径拼接错误。alias 也可用于非前缀匹配,但最常用于替换路径。
2. index、autoindex、try_files
index:定义默认查找的首页文件,按顺序尝试。nginxindex index.html index.htm;
当请求目录时(如/),会依次查找这些文件,返回第一个存在的。autoindex:开启目录列表,当没有index文件时显示文件清单。nginxautoindex on; # 开启 autoindex_exact_size off; # 显示更易读的文件大小 autoindex_localtime on; # 显示本地时间try_files:按顺序检查文件是否存在,以便实现前端路由、回退等功能。nginxlocation / { try_files $uri $uri/ /index.html; }
工作流程:尝试$uri对应的文件,不存在则尝试$uri/目录,都失败则内部重定向到/index.html。常用于 SPA 应用。
3. expires 缓存设置
控制 Expires 和 Cache-Control 头,让浏览器或 CDN 缓存静态资源。
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
expires 30d;表示 30 天后过期。- 也可用
expires -1;表示禁止缓存,expires epoch;强制使用 1970 时间点使缓存过期。
四、反向代理模块
Nginx 作为反向代理时,核心是 proxy_pass 及相关指令。
1. proxy_pass 后的 URI 有无斜杠的区别(重点)
这是配置反向代理时最经典的陷阱。proxy_pass 后是否带路径,直接影响请求 URI 如何传给后端。
- 如果
proxy_pass后没有 URI 或特别指定替换规则:会将完整的原始请求 URI 追加到指定地址。 - 如果
proxy_pass后带了 URI(哪怕是单纯的一个/),Nginx 会将location匹配的部分替换为该 URI。
假设请求为 http://example.com/api/users?id=1:
| 配置 | 传递给后端的 URI | 说明 |
|---|---|---|
location /api { proxy_pass http://backend; } | /api/users?id=1 | proxy_pass 无URI,完整转发 |
location /api { proxy_pass http://backend/; } | //users?id=1 | 匹配 /api(无斜杠),剩余部分带前导斜杠 /users,与 / 拼接成双斜杠,是经典踩坑点 |
location /api/ { proxy_pass http://backend/; } | /users?id=1 | 匹配 /api/(带斜杠),剩余部分 users 无前导斜杠,与 / 拼接后结果正常 |
location /api { proxy_pass http://backend/app; } | /app/users?id=1 | 替换 /api 成 /app |
location = /api/test { proxy_pass http://backend/test; } | /test | 精确匹配,完全替换 |
核心口诀:proxy_pass 后面不含路径则原样透传,含路径则替换 location 匹配部分。强烈建议保持 location 后的路径与 proxy_pass 后路径的斜杠对应(同带或同不带),否则容易出现双斜杠或缺斜杠的意外结果。
2. proxy_set_header 透传真实 IP、Host 等
后端服务器通常需要客户端的真实信息,必须显式设置头信息。
location / {
proxy_set_header Host $host; # 传递域名
proxy_set_header X-Real-IP $remote_addr; # 客户端真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 代理链路
proxy_set_header X-Forwarded-Proto $scheme; # 原始协议
proxy_set_header X-Forwarded-Host $host;
proxy_pass http://backend;
}
注意:默认 Nginx 可能会透传 Host,但很多场景需要显式指定避免后端拿到错误的 Host。如果后端需要获取客户端 IP,需配置 --with-http_realip_module 且后端信任 Nginx 传递的 X-Forwarded-For。
3. 超时设置
| 指令 | 含义 | 示例 |
|---|---|---|
proxy_connect_timeout | 与后端建立连接的超时(握手时间) | proxy_connect_timeout 10s; |
proxy_read_timeout | 等待后端响应的超时(两次读之间间隔) | proxy_read_timeout 60s; |
proxy_send_timeout | 向后端发送请求的超时 | proxy_send_timeout 60s; |
proxy_buffering | 开启或关闭代理缓冲 | proxy_buffering on; |
合理设置超时可避免慢后端拖垮 Nginx,同时配合 proxy_next_upstream 错误处理。
五、负载均衡
利用 upstream 块定义后端服务器组,并通过多种策略分发流量。
1. upstream 块定义
upstream backend {
server 10.0.0.1:80 weight=3;
server 10.0.0.2:80;
server 10.0.0.3:80 backup;
}
然后在 location 中使用:
location / {
proxy_pass http://backend;
}
2. 调度策略(NGINX Plus 拥有更多高级策略,以下为社区版):
- 轮询(默认):请求按顺序逐一分配。
weight:加权轮询,性能高的机器分配更多请求。nginxserver backend1.example.com weight=5; server backend2.example.com weight=1;ip_hash:根据客户端 IP 哈希来固定后端,解决 Session 保持问题。nginxupstream backend { ip_hash; server ... }least_conn:把请求发给当前活跃连接数最少的服务器,适合长连接场景。nginxupstream backend { least_conn; server ... }fair(第三方):按后端响应时间来分配,需安装nginx-upstream-fair模块。random(1.15.1+):随机选择,可加two参数随机选两个再从中挑最少连接,用于分布式环境。
3. 后端健康检查
- 被动检查:Nginx 自动进行。当请求失败(连接超时、错误码等),会标记该服务器为
down一段时间,通过max_fails和fail_timeout控制。意味着 30 秒内失败 3 次就会暂停使用 30 秒。nginxserver 10.0.0.1 max_fails=3 fail_timeout=30s; - 主动健康检查:社区版不自带,需通过第三方模块(如
nginx_upstream_check_module)或 Nginx Plus 实现,可定期探测后端/health端点。
六、Rewrite 与重定向
控制 URL 的重写与跳转,配合变量实现灵活规则。
1. return 指令
最简单直接的重定向,用于停止处理并返回状态码。
# 域名重定向
server {
listen 80;
server_name old.com;
return 301 http://new.com$request_uri;
}
# HTTP 跳转 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
优点:执行效率极高,比 if 安全,能快速终止请求。
2. rewrite 指令
rewrite regex replacement [flag];
用于内部重写或条件重定向,有四种 flag:
last:停止当前 rewrite 指令,用新的 URI 重新开始 location 匹配(类似内部转发)。break:停止 rewrite,不再继续匹配 location,直接使用当前上下文处理。redirect:返回 302 临时重定向。permanent:返回 301 永久重定向。
常见场景:
- 伪静态:
rewrite ^/article-(\d+)\.html$ /article.php?id=$1 last; - 强制 HTTPS:结合
if,但建议优先使用return。 - 路径清理:去掉重复斜杠等。
3. if 的谨慎使用
if 指令容易产生非预期行为,因为它不按标准的 rewrite 流程工作。常见的坑:
if中包含proxy_pass可能导致未预期的变量错误。- 尽量避免在
location内用if进行复杂的逻辑,优先使用try_files和map。
若必须使用 if,最好仅限于 return 或 rewrite 操作。例如:
if ($http_user_agent ~* "bot") {
return 403;
}
七、HTTPS 配置
现代化 Web 标配,Nginx 能高效终结 SSL/TLS。
1. 基础证书配置
server {
listen 443 ssl;
http2 on; # nginx 1.25.1+ 用独立的 http2 指令
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt; # 证书文件(含中间证书)
ssl_certificate_key /etc/nginx/ssl/example.com.key; # 私钥文件
# 会话缓存提升 TLS 握手性能
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
}
版本注意:nginx 1.25.1 起,
listen指令的http2参数已废弃,改用独立的http2 on;指令(同一server块内,listen只负责端口与ssl)。1.25.0 及更早版本仍需用listen 443 ssl http2;这种旧写法。
2. 协议与算法优化
ssl_protocols TLSv1.2 TLSv1.3; # 仅启用安全协议
ssl_ciphers EECDH+AESGCM:EDH+AESGCM; # 高强度加密套件
ssl_prefer_server_ciphers on; # 优先使用服务器端加密套件
# OCSP Stapling:减少客户端验证证书的延迟
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ssl_ciphers需根据安全标准定期更新,例如禁止 RC4。- OCSP Stapling:服务器在握手中附带 OCSP 响应,客户端无需单独查询,加快建立连接。
3. HTTP/2 开启与优势
nginx 1.25.1+ 用独立的 http2 on; 指令(旧版本用 listen 的 http2 参数,见上文版本注意):
listen 443 ssl;
http2 on;
优势:基于二进制分帧,支持多路复用(同一连接上并行请求)、头部压缩 HPACK,显著减少延迟,提升页面加载速度。但 HTTP/2 必须配合 HTTPS,因此证书配置是前提。
注意:HTTP/2 服务器推送(Server Push)已在 nginx 1.25.1 中移除(
http2_push指令不再可用),该特性因浏览器普遍不支持及实际收益有限已被业界弃用,如需类似效果可考虑Link: <...>; rel=preload响应头或 HTTP/3。
全站 HTTPS + HTTP/2 典型配置框架:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name example.com;
# 证书与安全配置...
# 业务 location 配置...
}
掌握这些核心模块与指令,你就拥有了解决绝大多数 Nginx 场景的弹药库。不管是静态加速、反向代理、负载均衡还是 HTTPS 配置,都能得心应手。建议在测试环境中实际演练每个指令,尤其是 location 优先级和 proxy_pass 的 URI 处理,亲自看日志验证行为,印象会更加深刻。
参考文献
相关文章
安全基础
Nginx 作为流量的总入口,安全配置是防线第一关。以下从六个基础维度加固你的服务,既实用又立竿见影。
配置文件结构与语法
下面我们深入到 Nginx 的配置核心——配置文件的结构、语法和变量系统。这一部分是你驾驭 Nginx 的“语法手册”。
Nginx 核心概念
Nginx 是一款高性能的 HTTP 和反向代理服务器。学习路径见 运维导读。它的强大并发能力与灵活的扩展性根植于少数几个核心设计。理解这些底层原理,后续的配置、调优和排障都会变得通透。
常见故障排查思路
故障排查的关键是快速定位,而非盲目重试。下面按最常见的五种现象归类,每一种都给出清晰的排查路径和解决思路。
性能调优基础
性能调优的目标是:用有限的资源,支撑更高的并发、更快的响应、更稳的服务。下面按优化维度,逐一拆解原理和配置要诀。
访问日志与错误日志
日志是 Nginx 排错的“第一现场”。一个优秀的日志策略既能完整保留请求上下文,又不会撑爆磁盘。下面从格式定制、存储轮转、错误分级三个维度详细讲解。