Nginx 502 Bad Gateway 排查思路与常见原因

Cold 发布于 2022-06-11 35 次阅读 709 字 预计阅读时间: 3 分钟 问题排查


502 大概是最常见的线上报错之一。它本质就一句话:Nginx 作为代理,没能从后端拿到合法响应。但"没能拿到"的原因能列出十几种。这篇把我遇到过的场景整理成一个排查清单,按命中率排序,遇到 502 直接照着过一遍。

排查第一步永远是错误日志

tail -f /var/log/nginx/error.log

刷新页面复现一次,日志里那行会告诉你具体原因:connect() failed 是连不上后端,upstream timed out 是超时,no live upstreams 是后端全挂了。90% 的 502 靠这行日志就能定位方向。

常见原因清单(按我遇到的概率排序)

1. 后端进程挂了 / 没起来。最常见。发版脚本起服务失败、OOM 被杀、代码报错崩了。ps -ef | grep java 或看后端日志确认。表现:connect() refused。

2. 端口/socket 对不上。proxy_pass 写的 8080,后端实际起在 8081(改了配置忘了同步);或者 PHP 场景 php-fpm 挂了、socket 文件路径不对。ss -tlnp | grep 8080 验证。

3. 超时。后端太慢,超过 Nginx 的 proxy_read_timeout(默认 60s)被掐断。偶发 502 + 后端其实还在处理,八成是这个。处理要么修后端慢的问题,要么适当调超时:

proxy_connect_timeout 5s;
proxy_read_timeout    60s;
proxy_send_timeout    60s;

4. 缓冲区不够。后端一次吐了个超大响应头(比如过长的 Set-Cookie),header 缓冲区放不下。日志里会看到 "upstream sent too big header"。调整:

proxy_buffer_size 32k;
proxy_buffers 8 32k;

5. keepalive 连接被后端单方面关闭。上游长连接池里的连接被后端(比如某些网关 60s 空闲断开)关了,Nginx 拿着半死连接去请求就 502。特征是低流量时偶发。加 proxy_next_upstream error timeout http_502; 让 Nginx 自动重试下一个上游,或 upstream 里配 keepalive 32; + proxy_set_header Connection "";。

6. 文件句柄 / 连接数打满。日志里 "too many open files"。ulimit -n 调大,systemd 管理的服务要在 service 文件里加 LimitNOFILE=65535。

一个排查模板

  • error.log 那行错误 → 确定方向(拒绝连接 / 超时 / 头太大)
  • 后端进程在吗?端口对吗?→ ps + ss
  • 绕过 Nginx 直连后端(curl 127.0.0.1:8080)→ 区分是 Nginx 的问题还是后端的问题
  • 后端日志同一时刻有没有异常 → 应用层面的崩溃/慢查询
  • 偶发的话统计时间点规律 → 定时任务/发版窗口/流量高峰的关联

把这套流程走过几遍之后,502 从"可怕的事故"会变成"十分钟的事故"。排查能力本质上是把常见故障路径内化成清单。

和喜欢的一切在一起~
最后更新于 2022-06-11