Nginx 配置速查表
Nginx 常用配置速查:server、location、proxy_pass、upstream、ssl、gzip、rewrite 等高频指令与片段对照,附中文说明,运维部署与排障时快速查阅。
原理解析
Nginx 是事件驱动的高性能 Web 服务器与反向代理。配置呈层级:http 块包含多个 server(虚拟主机),每个 server 内含若干 location(按 URI 前缀/正则匹配请求),指令自下而上、就近生效。
常见职责:反向代理(proxy_pass 把请求转发到后端)、负载均衡(upstream + 多种策略)、静态文件服务、TLS 终止、gzip 压缩与缓存。location 的正则匹配顺序(^~、~、~*)会显著影响路由结果,须谨慎。
实务上最值得先做对的两件事:一是把 server_name 与 location 的匹配关系画出来确认一遍,多数「配置不生效」源于顺序或正则优先级 misunderstood,而非指令写错;二是给每个 location 配 access_log 标记,排查时能直接按路径分组统计状态码,胜过逐条 grep。最后,改完配置务必先 nginx -t 验证语法再 reload —— 语法错误下 reload 会保留旧配置且不报错,很容易让人以为新配置已生效。
关于缓冲与超时的组合也值得留意:proxy_buffering 决定响应是否先落磁盘再发给客户端,关闭它可以降低首字节延迟但会让后端承担更多并发压力;proxy_read_timeout 与 send_timeout 表达的是不同方向的等待(读后端 vs 写客户端),只调一个往往解决不了超时问题。出现 504 时先确认是读后端超时,而不是客户端写超时。
什么时候该查这张表
这张表在你要排查「配置改了但不生效」或「反代/缓存行为异常」时有用。nginx 的指令分 main / events / http / server / location 五个层级,作用域与覆盖关系是绝大多数困惑的来源。
不该查的情况:你在做应用层的负载均衡策略或健康检查设计。nginx 提供了基础能力,但策略好坏取决于业务,配置片段只是手段。
判断标准:指令不生效先查「作用域是否覆盖」与「是否被更高优先级 location 抢先匹配」;反代出问题先查 proxy_pass 结尾斜杠的语义差异。这两类问题占实际故障的大多数。
特别注意 include 的位置决定上下文:把片段放在 http 块里,它能引用 http 级指令;放进 server 块就多了一层限制。同一个片段放在不同位置,能用的指令集合是不同的。
边界与常见陷阱
proxy_pass 末尾斜杠决定 URI 是否被替换
location /api/ 配 proxy_pass http://backend/ (末尾有斜杠):请求 /api/users 被替换为 /users 转发。配 proxy_pass http://backend (无斜杠):请求 /api/users 原样转发为 /api/users。这个差异是最常见的「反代 404」根因——请求进了后端但路径对不上。批量排查时先把 location 与 proxy_pass 的斜杠对齐,再看其他配置。
location 匹配有优先级,精确匹配会抢先
匹配顺序为:精确 = 前缀(^~)> 正则(~ / ~*)> 普通前缀(按最长匹配)。因此一个 location / 会抢走所有未被更精确规则命中的请求,而一个写错的正则可能让本该走静态文件的请求落到反代上。这也是为什么「加了 location 但请求没变」很常见——新规则被优先级更高的规则截走了。
try_files 与 error_page 的配合顺序会掩盖 404
try_files ... =404 之后的 error_page 404 /404.html 会把真实缺失路径也渲染成同一张自定义页,于是「上游返回 404」和「本地文件不存在」两种情况在日志里无法区分。排查时要同时看 error_log 与 access_log:只有 access_log 里的 404 状态而没有 upstream 记录,才说明是本地未命中。
header 指令的继承与「重复添加」
add_header 不会覆盖上级已有的同名/相关头,而是追加,所以多层配置后可能出现两个 X-Frame-Options 或两个 Cache-Control,后者会让缓存行为变得不可预测。nginx 1.29 起提供 add_header_inherit 合并子级头;在此之前,惯用做法是声明变量再用正则式 include 统一注入,而不是在多个层级各写一次。
与相邻内容的分工
要查 HTTP 状态码语义(502 与 504 的区别、304 怎么产生),用站内「HTTP 状态码」页;本页只讲 nginx 如何处理它们。
证书与 HTTPS 配置属于站内证书相关工具与参考;本页的 HTTPS 片段只覆盖最常见的路径,不含证书链排错。
反代后的缓存行为要配合 Cache-Control 与 ETag 理解,本页不覆盖 HTTP 缓存语义本身。
若需要系统级排障命令(ss/lsof 查端口、journalctl 看启动日志),属运维范畴,不在本速查表内。
实战片段
要点:① proxy_pass 末尾斜杠与 location 前缀必须成对,否则 /api/users 会原样转发成 /api/users 造成 404;② 正则 location 优先级高于普通前缀,静态资源规则写错会把请求抢到反代上;③ add_header 是追加不是覆盖,多层配置会产生重复头,惯用做法是变量 + 正则 include 统一注入;④ SPA 必须 try_files 回退到 index.html,否则深链接刷新直接 404。
# 反向代理:注意两个 location 前缀与 proxy_pass 的斜杠要「成对」
location /api/ {
# 末尾 / → /api/users 转发为 /users
proxy_pass http://backend_upstream/;
proxy_http_version 1.1;
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_set_header X-Forwarded-Proto $scheme;
# 上游先扛 3 秒,再交给 nginx 重试
proxy_connect_timeout 3s;
proxy_read_timeout 30s;
# 用变量 + 正则 include 统一注入头,避免 add_header 多层重复
set $CSP_DEFAULT "default-src 'self'";
include /etc/nginx/snippets/csp.conf;
}
# 静态资源:长缓存 + 内容哈希文件名
location ~* \.(?:js|css|woff2|png|svg|webp)$ {
expires 1y;
add_header Cache-Control "public, immutable" always;
access_log off; # 高频静态资源不写 access_log
try_files $uri =404;
}
# 单页应用:不存在则回退到 index.html(SPA 路由必需)
location / {
try_files $uri $uri/ /index.html;
}实践注解
- location 的匹配优先级不按书写顺序精确匹配 = 最高,其次 ^~ 前缀,再是正则 ~,最后是普通前缀。因此写在前面的普通前缀会被后面的正则截胡。排查「规则没生效」时先确认匹配优先级,而不是反复改写法。
- proxy_pass 尾部斜杠决定路径是否被替换proxy_pass http://up/ 会丢掉 location 前缀,proxy_pass http://up 则保留。少一个斜杠就会出现「后端收到 /api/api/xxx」这类重复前缀,是本类配置最常见的错误。
- 静态文件 location 漏掉 try_files 会返回 404前端单页应用的深层路由在磁盘上没有对应文件,必须 try_files $uri $uri/ /index.html 回退,否则刷新即 404,而站内跳转却正常——这个差异会让问题看起来「偶发」。
数据来源
- nginx documentation (nginx.org/en/docs)
- Mozilla SSL Configuration Generator
上述编号、名称与定义均来自公开规范,本站不主张对规范数据本身的独创性;本页的编排方式、中文释义与实践注解由本站撰写。
| 指令 / 片段 | 说明 |
|---|---|
| listen 80; | 监听端口(ssl 用 443 ssl) |
| server_name example.com; | 虚拟主机域名 |
| root /var/www; | 站点根目录 |
| index index.html; | 默认首页文件 |
| location / { } | 前缀路径匹配块 |
| location = /api { } | 精确匹配(优先级最高) |
| location ~ \.php$ { } | 正则匹配(区分大小写) |
| proxy_pass http://backend; | 反向代理到上游 |
| proxy_set_header Host $host; | 透传原始 Host 头 |
| upstream backend { } | 定义负载均衡后端组 |
| try_files $uri $uri/ =404; | 按序尝试文件,失败 404 |
| rewrite ^/old /new permanent; | 301 重写重定向 |
| return 301 https://$host$request_uri; | 强制 HTTP 跳 HTTPS |
| ssl_certificate /path/fullchain.pem; | SSL 证书链路径 |
| ssl_certificate_key /path/privkey.pem; | SSL 私钥路径 |
| gzip on; | 开启响应 gzip 压缩 |
| client_max_body_size 10m; | 限制请求体大小 |
| auth_basic "Restricted"; | 开启基础认证弹窗 |
| add_header Cache-Control "max-age=3600"; | 设置缓存响应头 |
| access_log /var/log/nginx/access.log; | 访问日志路径 |
| error_log /var/log/nginx/error.log; | 错误日志路径 |
| nginx -t | 测试配置文件语法 |
| nginx -s reload | 平滑重载配置(不中断) |
| nginx -s stop | 快速停止服务 |
常见问题
如何配置 Nginx 反向代理?
在 server 块里用 location 匹配路径,再用 proxy_pass http://后端地址; 转发;通常配合 proxy_set_header Host $host;、proxy_set_header X-Real-IP $remote_addr; 透传客户端信息。后端可以是 upstream 组实现负载均衡。
如何强制把所有 HTTP 请求跳转到 HTTPS?
用一个监听 80 的 server 块:return 301 https://$host$request_uri;,把明文请求 301 重定向到同域名 HTTPS;HTTPS 的 server 块再配置 ssl_certificate 与 ssl_certificate_key。
如何配置负载均衡(upstream)?
在 http 块定义 upstream backend { server 10.0.0.1:8080; server 10.0.0.2:8080; },默认轮询;可加 weight= 调权重、ip_hash; 做会话保持;location 内 proxy_pass http://backend; 引用。
修改配置后如何让生效?
先 nginx -t 校验语法,确认无误后 nginx -s reload 平滑重载(已建连接不中断);若 Nginx 未运行则用 nginx 启动。reload 不会丢流量,优于 stop 再启动。