Nginx 反向代理 502/504 排查:先分清是谁超时,再按这四步定位

举报
yd_227538180 发表于 2026/11/10 10:24:04 2026/11/10
【摘要】 502 是上游没有给出合法响应,504 是上游响应太慢。本文先通过 Nginx 日志定性,再绕过 Nginx 直测上游、区分三个超时参数、检查资源与健康检查,按四步定位 502/504,并附可直接套用的排查清单。

线上服务突然返回 502 Bad Gateway 或 504 Gateway Timeout,第一反应往往是“重启 Nginx”。但 502 和 504 背后的原因完全不同:502 是上游没有给出合法响应,504 是上游响应太慢。先分清是哪一种,再动手,能少走很多弯路。本文按一次真实的线上排查顺序,把方法固定成四步。

一、第一步:先看日志定性,不要先改配置

Nginx 的 error_log 是第一现场。先看最近一分钟的报错,再看 access_log 里的上游状态码和耗时:

tail -n 200 /var/log/nginx/error.log
awk '{print $9, $NF}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

常见的三类定性信号要分清:

  • upstream prematurely closed connection:上游在返回完整响应前断开了连接,多半是上游进程崩溃、被 OOM 杀掉,或者后端主动关闭了连接。
  • no live upstreams:上游全部被标记为不可用,Nginx 已经没有可用的后端可以转发。
  • upstream timed out:Nginx 在等待上游时超时,这通常对应 504,而不是 502。

同时在 access_log 里记录 $upstream_status 和 $upstream_response_time,如果状态码是 502 但上游耗时很短,问题多半在连接阶段;如果耗时恰好卡在 proxy_read_timeout 的数值附近,问题多半在上游处理太慢。

二、第二步:502 先绕过 Nginx,直接测上游

502 的核心问题是“上游没给合法响应”。最直接的办法是绕过 Nginx,直接请求后端:

curl -v http://127.0.0.1:8080/health
ss -tlnp | grep 8080
ps aux | grep -E 'java|gunicorn|php-fpm' | grep -v grep

按这个顺序排查:

  1. 端口是否在监听:后端进程没起来、监听地址写成了 127.0.0.1 但 Nginx 配的是内网 IP、端口号写错,都会直接 502。先核对 nginx.conf 里的 upstream 地址和后端实际监听地址是否一致。
  2. 进程是否还活着:用 systemctl status 看后端服务状态,再看 dmesg 或系统日志有没有 OOM Killer 的记录。服务刚部署完就 502,优先查启动日志,而不是反复重启 Nginx。
  3. 协议是否对得上:Nginx 用 http 协议转发,后端却只监听了 https,或者后端要求 SNI、要求特定的 Host 头,也会返回非法响应。可以用 curl 加上 -H "Host: xxx" 逐项复现。
  4. 权限与连接数:Unix Socket 方式转发时,Socket 文件权限不对、后端连接池打满,同样会表现为 502。检查 Socket 文件的属主和权限,以及后端的连接数上限。

如果绕过 Nginx 直接访问后端也是失败的,问题就在后端本身,不要再调 Nginx 的超时参数。

三、第三步:504 先分清是谁慢,再决定调哪个超时

504 的核心问题是“上游太慢”。Nginx 有三个超时要分清:

  • proxy_connect_timeout:和上游建立连接的超时,默认 60 秒,一般不用动。
  • proxy_send_timeout:向发送请求体的超时。
  • proxy_read_timeout:等待上游响应的超时,这是 504 最常见的触发点。

排查顺序建议这样:

  1. 看 $upstream_response_time:如果每次都恰好等于 proxy_read_timeout,说明后端确实在规定时间内没有返回。
  2. 在后端侧看慢日志:数据库慢查询、外部接口调用耗时、文件上传后的同步处理,都是常见拖慢点。先看后端的耗时分布,再决定是优化代码还是调整超时。
  3. 只在确认后端偶发变慢、且业务允许等待时,才适度调大 proxy_read_timeout,例如从 60 秒调到 120 秒,并且同步检查后端和数据库的连接池是否够用。
location /api/ {
    proxy_pass http://backend;
    proxy_connect_timeout 5s;
    proxy_send_timeout 60s;
    proxy_read_timeout 120s;
}

注意不要把超时无限制调大:超时调得越大,慢请求占用的连接就越多,一旦后端真的卡死,Nginx 的 worker_connections 很快会被占满,整个站点都会跟着不可用。调超时之前,先确认后端有熔断或限流兜底。

四、第四步:查资源与健康检查,避免反复复发

前三步解决的是单次故障,第四步解决的是反复复发:

  • 上游健康检查:用 max_fails 和 fail_timeout 把连续失败的上游暂时摘掉,避免 Nginx 把请求继续发给已经挂掉的后端。
  • 连接复用:开启 keepalive,减少每次请求都新建连接的开销。没有 keepalive 的高并发场景,后端端口容易被 TIME_WAIT 占满。
  • 文件描述符与连接数:worker_connections、系统 ulimit、后端连接池上限要一起看。Nginx 报错 too many open files 时,调大 Nginx 配置之前,先看系统和进程的句柄数上限。
  • 发布与回滚:502 经常出现在刚发布之后,先用 nginx -t 检查配置语法,再用 nginx -s reload 平滑加载,避免直接重启造成短暂中断。
nginx -t
nginx -s reload

五、一个可直接套用的排查清单

现象 先看什么 最可能的原因
502,耗时很短 error_log、上游进程 后端挂了、端口或地址配错
502,间歇出现 max_fails、后端连接数 后端连接池满、偶发崩溃
504,耗时卡在超时值 上游耗时、慢查询日志 后端处理慢、外部接口慢
504,只在个别接口出现 该接口的耗时分布 特定接口的慢 SQL 或大文件处理

总结一句话:502 先查连接和进程,504 先查耗时和慢日志;先定性再调参,先修后端再调 Nginx。把日志、上游状态码和上游耗时这三项固定下来,大多数 502/504 都能在十分钟内定位到责任方。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。