nginx 502/504 排查步骤:从 upstream 超时到后端假死逐层定位 核心要点图解,先看 nginx error.log 定位是连接超时还是读超时。;upstream timed out 优先查后端处理时长与超时配置。;后端假死常因进程阻塞,用 strace 和 ss 查连接状态。;调大 proxy_read_timeout 治标,优化后端性能治本。
nginx 502/504 排查步骤:从 upstream 超时到后端假死逐层定位 · 核心要点一图读懂(AegisX)

核心要点(TL;DR)

  • 先看 nginx error.log 定位是连接超时还是读超时。
  • upstream timed out 优先查后端处理时长与超时配置。
  • 后端假死常因进程阻塞,用 strace 和 ss 查连接状态。
  • 调大 proxy_read_timeout 治标,优化后端性能治本。

痛点引入:502/504 为何总在关键时刻出现?

作为运维或站长,你一定遇到过 nginx 突然返回 502 Bad Gateway 或 504 Gateway Timeout,业务瞬间不可用。这两个错误看似相似,根源却大不相同:502 通常是后端服务不可达或崩溃,504 则是后端处理超时。若不能逐层定位,往往只能盲目重启,问题反复出现。本文提供一套从 upstream 超时到后端假死的排查步骤,结合具体命令和检查清单,帮你快速恢复服务并根治隐患。

第一步:读懂 nginx 错误日志,锁定错误类型

nginx 的 error.log 是排查的第一现场。用以下命令实时过滤关键错误:

tail -f /var/log/nginx/error.log | grep -E "502|504|upstream"

典型日志如下:

  • connect() failed (111: Connection refused) while connecting to upstream —— 后端端口未监听或服务未启动,导致 502。
  • upstream timed out (110: Connection timed out) while reading response header from upstream —— 后端处理超时,导致 504。
  • no live upstreams while connecting to upstream —— 所有后端节点被标记为不可用,需检查健康检查配置。

根据日志中的 upstream 地址(如 http://127.0.0.1:8080),可快速定位故障节点。同时检查 access.log 中的 upstream_status 和 upstream_response_time 字段,统计各后端错误率与响应时间分布。

第二步:检查 upstream 超时配置与后端响应时间

若日志显示 upstream timed out,先确认 nginx 的超时参数是否合理。关键指令:

  • proxy_connect_timeout:与后端建立连接的超时,默认 60s。
  • proxy_send_timeout:向后端发送请求的超时,默认 60s。
  • proxy_read_timeout:等待后端响应的超时,默认 60s。

用 nginx -T 查看当前生效配置。若后端接口平均响应时间为 2s,但偶尔有 10s 的慢查询,可将 proxy_read_timeout 调整为 30s,并配合 proxy_next_upstream 实现重试:

proxy_next_upstream error timeout http_502 http_504;
proxy_next_upstream_tries 2;

但调大超时只是治标,需进一步分析后端为何慢。使用 curl -o /dev/null -s -w "%{time_total}" http://backend:8080/api 测试后端实际响应时间,或用 ab、wrk 压测,确认是否普遍超时。

第三步:诊断后端假死——进程存在但无法处理请求

后端假死是 504 的常见根因:进程还在,但线程池满、数据库连接池耗尽或死锁,导致新请求排队超时。排查步骤:

  1. 检查系统资源:top -Hp <pid> 查看线程 CPU 占用,若某线程持续 100%,可能陷入死循环;free -m 看内存是否耗尽引发频繁 GC。
  2. 查看连接状态:ss -tanp | grep <port> 观察 ESTAB 连接数是否接近上限,大量 CLOSE_WAIT 表示应用未正确关闭连接。
  3. 抓取线程栈:对于 Java 应用,jstack <pid> > thread.txt 分析线程阻塞情况;对于 C/C++,用 pstack <pid> 或 gdb -p <pid> -batch -ex "thread apply all bt"。
  4. 检查依赖服务:数据库、Redis 等是否响应缓慢,用 telnet db_host 3306 或 redis-cli ping 测试连通性。

若发现大量线程阻塞在数据库查询,需优化 SQL 或增加连接池;若线程池满,可调整线程池大小或增加限流。

第四步:分步解决与验证

根据定位结果采取对应措施:

现象可能原因解决动作
502 Connection refused后端服务未启动或端口错误启动服务,检查监听端口 ss -lntp
502 no live upstreams健康检查失败,节点被剔除检查后端健康检查接口,调整检查参数
504 upstream timed out后端处理慢或网络延迟优化后端性能,适当调大 proxy_read_timeout
504 伴随后端 CPU 高死循环或复杂计算抓线程栈定位热点代码,优化算法
504 伴随连接数高连接池耗尽或泄漏检查连接池配置,修复未关闭连接

调整配置后,用 nginx -s reload 重载,并持续观察 error.log 和业务监控,确认错误率下降。

第五步:防护建议与长效监控

为避免问题复发,建议建立以下防护措施:

  • 为 upstream 配置健康检查(开源版可用 nginx_upstream_check_module),自动隔离故障节点。
  • 设置合理的超时与重试策略,避免雪崩。
  • 监控后端响应时间、错误率及系统资源,设置告警阈值。
  • 定期进行压力测试与容量评估,提前发现瓶颈。

在安全防护层面,可借助 AegisX 的实时监控与异常检测能力,对 nginx 错误日志和后端性能指标进行关联分析,提前预警潜在故障,减少人工排查成本。

行动建议

下次遇到 502/504,不要急着重启。按本文步骤:先看 error.log 区分错误类型,再查超时配置与后端响应时间,最后深入诊断后端假死。收藏这份检查清单,并建立常态化监控,才能让服务更稳定。

常见问题(FAQ)

nginx 502 和 504 有什么区别?

502 Bad Gateway 表示 nginx 从后端收到无效响应(如连接被拒、进程崩溃),504 Gateway Timeout 表示 nginx 等待后端响应超时。502 多因后端服务未启动或端口错误,504 多因后端处理慢或网络延迟。排查时 502 先查后端存活,504 先查超时配置与后端性能。

如何快速定位 nginx 502 是后端哪台机器的问题?

查看 nginx error.log 中 upstream 字段,会记录后端 IP 和端口。例如:upstream: "http://127.0.0.1:8080"。结合 access.log 的 upstream_addr 变量,可统计各后端错误率。用 grep 过滤 error.log 中 502 记录,快速锁定故障节点。

proxy_read_timeout 设置多少合适?

默认 60 秒,建议根据后端接口平均响应时间设置,通常为平均耗时的 2-3 倍。对于长轮询或文件上传,可单独用 location 调大。不宜盲目设太大,否则故障时请求堆积。可结合 proxy_connect_timeout 和 proxy_send_timeout 一起调整。

后端假死有哪些常见原因?

常见原因包括:数据库连接池耗尽、线程池满、死锁、内存泄漏导致 GC 停顿、磁盘 I/O 阻塞。表现为进程存在但无法处理新请求。用 top 看 CPU,用 jstack 或 pstack 查线程栈,用 ss 看连接状态,可快速判断假死类型。

如何预防 nginx 502/504 反复出现?

建议:1) 配置健康检查(如 nginx plus 或开源模块),自动剔除故障节点;2) 设置合理的超时与重试;3) 监控后端响应时间与错误率;4) 后端服务增加限流与熔断;5) 定期压测与容量规划。AegisX 可提供实时监控与自动告警,帮助提前发现异常。