Nginx 502 与 504 排查实战:从错误日志到上游、超时与安全组的七步流程
Nginx 作为反向代理部署在云服务器上时,502 Bad Gateway 和 504 Gateway Timeout 是最常见的两类报错。它们看起来相似,根因却完全不同:502 说明 Nginx 连不上上游或上游返回了非法响应,504 说明连上了但上游迟迟不给结果。本文整理一套我在 ECS 上排查这两类问题的流程,每一步都有可直接执行的命令。
一、先看错误日志,区分 502 与 504
不要只看浏览器里的状态码,第一步永远是 Nginx 的 error.log:
tail -n 200 /var/log/nginx/error.log | grep -E "upstream|connect"
常见的几类关键字对应不同方向:
1. connect() failed (111: Connection refused) while connecting to upstream:上游进程没起来或端口不对。
2. upstream prematurely closed connection:上游进程崩溃或主动断开,多见于应用 OOM、被 kill。
3. upstream timed out (110: Connection timed out) while reading response header:上游处理太慢,对应 504。
4. no live upstreams:upstream 里所有节点都被标记为不可用。
二、确认上游服务是否存活
在 Nginx 所在机器上,直接绕过 Nginx 访问上游:
ss -lntp | grep 8080 curl -sv -o /dev/null -m 5 http://127.0.0.1:8080/health
如果端口没有监听,去看应用日志和 systemd 状态:
systemctl status myapp journalctl -u myapp --since "30 min ago" | tail -n 100 dmesg -T | grep -i -E "killed process|out of memory"
如果 dmesg 里出现 Out of memory,说明应用被内核 OOM Killer 杀掉,502 只是表象,需要调整堆内存或升级规格。
三、检查 Nginx 配置里的上游地址
很多 502 来自配置笔误:端口写错、域名解析变了、使用了 localhost 却只监听 IPv4。先验证配置再重载:
nginx -t nginx -T | grep -n -E "proxy_pass|upstream|server "
特别注意:proxy_pass 里如果写的是域名,Nginx 只在启动或重载时解析一次。上游迁移到新 IP 后如果没有重载,就会一直连旧地址。可以用 resolver 配合变量,或者在变更后执行 nginx -s reload。
四、504:调整超时,但先找慢的原因
Nginx 默认的 proxy_read_timeout 是 60 秒。遇到 504 时,千万不要上来就把超时改成 600 秒,这只是把问题藏起来。正确顺序是:
1. 在日志格式里加上 $upstream_response_time 和 $request_time,统计哪些接口慢。
2. 用 awk 找出最慢的请求:
awk '{print $NF, $7}' /var/log/nginx/access.log | sort -rn | head -20
3. 确认慢在数据库、外部接口还是应用本身,再针对性优化。
4. 确实是导出、报表之类的长耗时接口,才对单个 location 单独放宽超时:
location /export/ {
proxy_pass http://backend;
proxy_connect_timeout 5s;
proxy_read_timeout 300s;
}
五、检查连接数与文件描述符
高并发下,Nginx 或上游可能因为连接数、文件描述符耗尽而拒绝新连接,日志里会出现 Too many open files 或 worker_connections are not enough。检查方法:
cat /proc/$(cat /run/nginx.pid)/limits | grep "open files"
ss -s
ss -ant | awk '{print $1}' | sort | uniq -c
如果 TIME_WAIT 很多,可以让 Nginx 与上游之间使用长连接:在 upstream 中配置 keepalive 32,并在 location 里设置 proxy_http_version 1.1 和 proxy_set_header Connection ""。同时把 worker_rlimit_nofile 与 worker_connections 调到合适的值,并确认系统层面的 LimitNOFILE 一致。
六、排查安全组与网络
当 Nginx 与上游不在同一台机器时,502 还可能来自网络层。在 Nginx 机器上执行:
nc -zv 192.168.1.20 8080 traceroute -n -T -p 8080 192.168.1.20
连不通时,去云平台控制台检查上游所在 ECS 的安全组入方向规则,是否放通了 Nginx 所在机器的内网地址和对应端口;同时检查系统防火墙 firewalld 或 iptables。我遇到过一次升级后新增了安全组但没有放通应用端口,现象就是间歇性 502,因为只有一部分节点受影响。
七、上线后的防护建议
1. 为 upstream 配置 max_fails 和 fail_timeout,并给应用提供 /health 健康检查接口。
2. 日志里固定记录 $upstream_addr、$upstream_status、$upstream_response_time,出问题时一眼能定位到哪个节点。
3. 对应用进程用 systemd 配置 Restart=on-failure,并监控内存和连接数。
4. 变更上游地址后,把 nginx -t 和 reload 写进发布脚本,避免遗漏。
总结
遇到 502 先查上游是否存活、端口与配置是否正确;遇到 504 先找慢请求,再决定是否放宽超时;批量出现的偶发错误,多半与连接数、文件描述符或安全组有关。按“日志、上游、配置、超时、资源、网络”的顺序排查,大多数问题几分钟内就能定位。
- 点赞
- 收藏
- 关注作者
评论(0)