502表示后端返回无效响应,504表示后端超时未响应;需通过error.log关键词定位阶段,直连验证后端健康,分段检查proxy_*_timeout参数,并排查连接池、fd、端口耗尽等资源问题。

502 和 504 都是 Nginx 作为反向代理时返回的网关错误,但根源完全不同:502 表示后端给了一个“无效响应”,504 表示后端“根本没给响应”。抓错方向,修一个月也白搭。
看日志,先锁定错误类型和阶段
Nginx 的 error.log 是第一现场。打开它,重点搜这几类关键词:
- connect() failed (111: Connection refused) → 后端没监听、端口错、服务根本没启
- upstream prematurely closed connection → 后端处理中主动断连,常见于进程崩溃、OOM kill、PHP-FPM worker 耗尽
- upstream timed out (110: Connection timed out) → 连接建立超时,查网络、防火墙、后端是否卡在系统调用(如 fork 失败)
- upstream timed out (113: No route to host) → 网络层不通,目标 IP 不可达
- while reading response header from upstream → 已连上,但等不到响应头 → 典型 504 场景
注意日志里明确标注的阶段(connecting / sending request / reading header / reading body),这直接对应 proxy_*_timeout 的哪一段失效。
查后端状态,不只看“进程在不在”
别只执行 systemctl status 就以为万事大吉。要验证实际服务能力:
- 用
curl -v http://127.0.0.1:8080/health直连后端,看是否能拿到有效 HTTP 响应(状态码 200 + 完整 header) - 查后端资源瓶颈:
free -h(内存)、df -h(磁盘)、top -H -p $(pgrep -f "java|python|node")(线程级 CPU 占用) - 针对常见运行时专项检查:
• PHP-FPM:pm.status_path开启后访问/status?full,看active processes是否接近max_children
• Java(Tomcat/Spring Boot):查 GC 日志,看是否频繁 Full GC 或 STW 超长;用jstack抓线程快照,确认是否有大量 BLOCKED/WAITING 状态
• Node.js:用node --inspect或clinic doctor检查事件循环延迟和堆内存
核对超时与连接配置,三段路不能混为一谈
Nginx 内部把一次请求切为三段独立路径,每段有专属超时参数:
-
客户端 → Nginx:受
client_header_timeout、client_body_timeout、send_timeout控制 —— 错误日志若含 while sending to client,就调这里 -
Nginx → 后端(建连+发请求+收响应):
proxy_connect_timeout(建议 5–10s)、proxy_send_timeout(发请求体,建议 60s)、proxy_read_timeout(等响应头+体,504 主因,按业务设 60–300s) -
长连接复用:
keepalive_timeout(Nginx 与客户端之间)和proxy_http_version 1.1; proxy_set_header Connection ''; proxy_pass ...+upstream中keepalive 32;(Nginx 与后端之间)—— 缺失会导致频繁重建连接,加重后端压力
别只改 proxy_read_timeout 就去上线。如果后端实际响应时间是 8 秒,而你把 timeout 设成 90 秒,问题只是被掩盖;若后端已因连接池打满而拒绝新连接,加 timeout 反而让失败更慢暴露。
盯住上游健康与系统资源,很多 502 其实是“假死”
很多 502 并非服务宕机,而是“忙到吐不出合法响应”:
-
连接池耗尽:Redis、DB、HTTP Client 连接池满,后端线程全部阻塞在
getConnection()上 —— 查连接数、线程堆栈、连接池监控指标 -
文件描述符(fd)不足:
ulimit -n查当前限制,lsof -p $(pgrep nginx) | wc -l查 Nginx 实际使用量;系统级检查cat /proc/sys/fs/file-nr -
上游健康检查失效:默认 passive 检查(靠失败请求触发)太迟钝。启用
nginx-upstream-check-module或集成 Consul 做主动探活,提前剔除半死节点 -
端口耗尽(TIME_WAIT 占满):高并发短连接场景下,
netstat -ant | grep TIME_WAIT | wc -l若超 6w,需调优内核:net.ipv4.tcp_tw_reuse = 1、net.ipv4.ip_local_port_range = 1024 65535


















