常见故障排查思路
本文文件名为
seror.md(service error 缩写),对应本目录学习路径中「阶段 10:调优与安全」的故障排查部分;姊妹篇se.md为安全基础。核心概念见 Nginx 核心概念。
故障排查的关键是快速定位,而非盲目重试。下面按最常见的五种现象归类,每一种都给出清晰的排查路径和解决思路。
一、502 Bad Gateway
现象
浏览器显示 502 Bad Gateway,错误日志常见记录:
upstream prematurely closed connection while reading response header from upstream
含义
Nginx 作为反向代理时,能连接上后端服务器,但后端没有返回有效的 HTTP 响应(比如进程崩溃、端口未监听、返回了无法解析的垃圾数据)。
排查步骤
- 后端服务是否存活?bash
# 检查后端端口是否在监听 netstat -tlnp | grep <后端端口> # 直接 curl 后端地址,看是否返回正常 curl -v http://127.0.0.1:8080/
若直接访问后端就报错或连接拒绝,说明问题不在 Nginx,是应用服务挂了或未启动。 - 后端是否有语法错误或异常退出?
查看后端日志(PHP-FPM、Gunicorn、Node.js 进程)。PHP-FPM 超时、内存溢出、脚本致命错误等都会导致 502。 - Nginx 与后端协议不匹配
例如设置了proxy_http_version 1.1但后端不支持,或后端要求 HTTP/1.0。可尝试强制 HTTP/1.0。 - 后端响应头过大
如果后端返回的响应头超过proxy_buffer_size的限制(默认 4k 或 8k),Nginx 会直接中断并返回 502。可增大:nginxproxy_buffer_size 16k; proxy_buffers 4 32k; - PHP-FPM 进程数耗尽
当所有子进程都在处理请求时,新请求会等待,如果配合了超时,可能直接 502。调整pm.max_children并观察pm.status_path。
快速验证
用 curl -v https://yourdomain 看响应信息,同时 tail -f /var/log/nginx/error.log,对照上游地址和状态。
二、504 Gateway Timeout
现象
浏览器显示 504 Gateway Time-out,错误日志类似:
upstream timed out (110: Connection timed out) while reading response header from upstream
含义
Nginx 在指定的时间内没有从后端收到完整的响应。根本原因是后端处理耗时 > Nginx 等待的超时时间。
排查步骤
- 确认超时配置是否过短
查看当前
proxy_read_timeout(默认 60s):nginxlocation / { proxy_read_timeout 60s; }
如果后端任务本身就需要长时间运行(例如报表导出、大数据查询),适当调大此值:nginxproxy_read_timeout 300s;
同时可调整proxy_connect_timeout和proxy_send_timeout。 - 检查后端应用响应时间
在 Nginx 访问日志中启用
$upstream_response_time,观察哪类请求耗时高:nginxlog_format timing '$remote_addr - $request_time ' 'upstream=$upstream_response_time ' 'status=$status';
统计慢请求,针对性优化数据库查询、接口逻辑或第三方调用。 - 后端服务健康状态 即使连接建立,后端可能因高负载而无法在短时间内生成响应。查看应用服务器的 CPU/内存/线程。
- 网络延迟 如果后端部署在不同机房,检查网络 RTT,在超时设置中预留余量。
注意:不要盲目调高超时去掩盖应用性能问题,正确处理是:优化慢接口 + 适当超时 + 异步化长耗时任务。
三、403 Forbidden
现象
页面返回 403 Forbidden,错误日志常见:
directory index of "/data/www/" is forbidden
或
open() "/data/www/index.html" failed (13: Permission denied)
原因归类与解决
- 目录缺少索引文件且
autoindex未开启
当请求的是目录(如/),但该目录下没有index指令指定的文件(index.html,index.php等),又禁用了目录列表,Nginx 默认返回 403。
解决:添加索引文件或开启autoindex on;(仅限非敏感目录)。 - 文件系统权限问题
Nginx 的 worker 进程运行用户(如www-data)无权读取请求的文件或目录。bash# 检查文件权限和属主 ls -l /data/www/index.html
确保对该用户有 读权限(目录需有执行权限 x,文件需有读权限 r)。修正:bashchown -R www-data:www-data /data/www chmod 755 /data/www
同时检查父目录权限,整个路径都需要对 worker 用户至少可执行。 deny规则误伤
前面配置的allow/deny或deny all覆盖了正常 IP。
用curl -v观察请求,并在日志中看来源 IP 是否正确(是否经过了代理导致 IP 变化)。- 文件系统 ACL 或 SELinux
在 CentOS/RHEL 上,SELinux 可能阻止访问非标准 Web 目录。可临时setenforce 0测试,若恢复正常则调整上下文chcon -R -t httpd_sys_content_t /data/www或直接使用标准目录。
四、404 与 location 匹配问题
现象
明明文件存在,但访问返回 404 Not Found。
根本原因
请求 URI 没有按预想被正确的 location 处理,最终用错了 root 或 alias 路径。
排查思路
- 验证 location 匹配是否正确
在错误日志启用
debug级别(针对特定 IP),观察 location 匹配过程,或通过add_header回应测试:nginxlocation /app { add_header X-Location "app block"; }
然后用curl -I http://domain/app/查看返回的头部,确认命中了哪个块。 - 区分
root与alias误用root /data/www;加上请求/images/1.jpg查找的实际路径是/data/www/images/1.jpg。alias /data/www;加上请求/images/1.jpg查找的实际路径是/data/www/1.jpg。
请严格按照前面核心模块章节的对比检查配置。注意 alias 末尾要带/,如果 location 也带/。
- 正则优先级覆盖
如果定义了多个 location,写了正则,可能某个宽泛的正则先匹配而忽略了更准确的普通前缀。回顾 location 优先级:
=>^~>~ 或 ~*> 前缀。若无意中定义了~ \.php$匹配,可能把图片请求都传给 PHP,导致 404。调整匹配顺序或使用^~阻止正则。 - try_files 路径错误
如果
try_files写了$uri /index.html,但/index.html的实际路径拼接后不存在,也会产生 404。检查 root 指令继承关系。
快速验证:在配置中临时开启 error_log /tmp/nginx-debug.log debug; 并触发请求,查看文件路径。
五、重定向循环
现象
浏览器报 “ERR_TOO_MANY_REDIRECTS”,地址栏不断在两个 URL 间跳转。
常见原因与解决
- HTTP 到 HTTPS 的死循环
反向代理 Nginx 后面如果还有一个 Nginx 或 CDN 处理 HTTPS,前端 Nginx 发出 HTTP 请求,后端又跳转回 HTTPS,形成循环。
检查:proxy_set_header X-Forwarded-Proto $scheme;是否被正确设置,并且后端应用信任该头。对于 WordPress 等,可能需要配置$_SERVER['HTTPS'] = 'on'基于该头。 return 301的递归nginxserver { listen 80; server_name example.com; return 301 http://www.example.com$request_uri; }
如果www.example.com又解析回当前 server,且本 server 又跳转,即出现循环。
解决:确保跳转目标对应另一个 server 块,或者使用if ($host !~ ^www\.) { ... }有条件跳转。rewrite规则未加last或产生二次匹配
一个rewrite修改 URI 后,如果不加last,可能后续的 rewrite 规则又将其改回来。检查所有 rewrite 规则,确保有一个终止条件。- Cloudflare/CDN 的 SSL 配置不当
如果源站设置了强制 HTTPS,但 CDN 用 HTTP 回源,源站返回 301 到 HTTPS,CDN 继续用 HTTP 请求…… 需要设置 CDN 的加密模式为 “Full” 或 “Full (strict)”。
排查命令:
curl -L -v http://example.com 2>&1 | grep -E "^(> GET |< HTTP|Location:)"
观察跳转链,找出哪一步产生了出乎意料的 301/302。
六、首选排查武器:nginx -t 与错误日志
无论遇到什么问题,养成两个第一时间动作:
- 配置测试
nginx -t
每次修改配置后必须运行:bashnginx -t && nginx -s reload
它会检测语法错误、上下文错误,并打印出错文件名和行号,避免因错误配置导致服务中断。 - 紧盯错误日志
绝对多数问题都会在error_log留下痕迹。为方便排查,建议:bashtail -f /var/log/nginx/error.log
一旦请求出现异常,立刻就能看到具体的 upstream 状态、权限拒绝、重定向过多等详细说明。临时将日志级别调至warn或error过滤噪音:nginxerror_log /var/log/nginx/error.log error;
如果本地环境,可针对特定 IP 开启 debug 日志深入。
排错心法:遇到问题 → 看错误日志 → 重现请求并观察 → 定位具体 location/upstream → 逐个假设验证。始终保留一份已知正常的可回滚配置,对故障零容忍。
七、排障常备命令速查
| 命令 | 用途 |
|---|---|
nginx -t | 检查配置语法,改配置后的第一反应 |
nginx -s reload | 平滑重载配置,不中断现有连接 |
tail -f /var/log/nginx/error.log | 实时观察错误日志 |
curl -v -I <url> | 只看响应头,快速判断状态码与关键 Header |
netstat -tlnp | grep <port> | 确认端口是否被正确监听 |
nginx -V | 查看编译参数,确认是否包含所需模块(如 --with-http_ssl_module) |
把这张表贴在常用终端旁边,遇到问题先按顺序过一遍,往往能在几分钟内定位到大方向。
延伸阅读
- Nginx 核心概念:理解 Master-Worker、反向代理等原理,是看懂本文排错思路的前提。
- 安全基础:限流、IP 控制等安全配置本身也可能是故障(如误杀正常流量)的来源,出现异常 403/503 时可对照排查。
参考文献
| 资料 | 说明 |
|---|---|
| nginx 文档 | 官方 |
| 运维导读 | 学习路径 |
| nginx -V 参数说明 | 编译参数 |
相关文章
安全基础
Nginx 作为流量的总入口,安全配置是防线第一关。以下从六个基础维度加固你的服务,既实用又立竿见影。
配置文件结构与语法
下面我们深入到 Nginx 的配置核心——配置文件的结构、语法和变量系统。这一部分是你驾驭 Nginx 的“语法手册”。
核心模块与常见指令详解
深入 Nginx 的指令层,是配置落地的关键。下面按功能模块拆解,每个指令都说明含义、语法、典型示例,并点出极易踩坑的地方。
Nginx 核心概念
Nginx 是一款高性能的 HTTP 和反向代理服务器。学习路径见 运维导读。它的强大并发能力与灵活的扩展性根植于少数几个核心设计。理解这些底层原理,后续的配置、调优和排障都会变得通透。
性能调优基础
性能调优的目标是:用有限的资源,支撑更高的并发、更快的响应、更稳的服务。下面按优化维度,逐一拆解原理和配置要诀。
访问日志与错误日志
日志是 Nginx 排错的“第一现场”。一个优秀的日志策略既能完整保留请求上下文,又不会撑爆磁盘。下面从格式定制、存储轮转、错误分级三个维度详细讲解。
Series
nginx
7 / 7