Nginx 502 与 504 排查:从错误日志措辞定位到配置

举报
yd_228692151 发表于 2026/10/30 07:15:35 2026/10/30
【摘要】 Nginx 报 502 和 504,方向完全不同。502 是 Nginx 连上了上游却拿不到合法响应,504 是等上游响应等到超时。把这两类混在一起查,通常会在同一个配置项上反复改却不见效。下面按「先分类、再定位、最后改配置」的顺序说清楚。 一、先看错误日志里的具体措辞tail -n 200 /var/log/nginx/error.log502 常见的三种措辞,指向的原因不同:connec...

Nginx 报 502 和 504,方向完全不同。502 是 Nginx 连上了上游却拿不到合法响应,504 是等上游响应等到超时。把这两类混在一起查,通常会在同一个配置项上反复改却不见效。下面按「先分类、再定位、最后改配置」的顺序说清楚。

一、先看错误日志里的具体措辞

tail -n 200 /var/log/nginx/error.log

502 常见的三种措辞,指向的原因不同:

  • connect() failed (111: Connection refused) while connecting to upstream —— 上游端口没有进程在监听。后端挂了、只监听了 127.0.0.1、或者容器重建后 IP 变了。
  • upstream prematurely closed connection while reading response header from upstream —— 连接建立成功,但上游在写完响应头之前就关闭了连接。多是后端进程崩溃、OOM 被杀、或者应用自身超时先返回了空连接。
  • no live upstreams while connecting to upstream —— 负载均衡组里所有节点都被健康检查判定为不可用,问题在健康检查配置而不是业务代码。

504 只有一类措辞:

  • upstream timed out (110: Connection timed out) while reading response header from upstream

看到这一句,直接说明请求已经发出,上游在 proxy_read_timeout 内没有返回第一个字节。

二、确认请求到底有没有到后端

这一步能立刻把问题范围砍掉一半。在上游机器上看连接和日志:

ss -lntp | grep ':8080'
ss -tn state established '( sport = :8080 )' | head

如果 ss 里能看到来自 Nginx 的 established 连接,但后端应用日志里没有任何对应请求记录,说明请求卡在了应用前面的一层——比如容器网络的 iptables 规则、Service 的端点没更新、或者应用线程池耗尽导致连接被 accept 后一直不处理。

如果连接都建不起来,是网络层或监听地址的问题,跟 Nginx 的超时配置无关。

三、几个最容易配错的地方

1. 超时预算不匹配

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

proxy_read_timeout 是两次读操作之间的间隔上限,不是整个请求的总时长。上游如果每 50 秒吐一个字节,60 秒的配置永远不会触发。反过来,上游做批量导出这类长任务时,把 proxy_read_timeout 调到 300s 只是把 504 往后推,真正该做的是把长任务改成异步任务加轮询。

2. upstream 用了域名却只在启动时解析

upstream backend {
    server api.internal:8080;   # 只在 reload 时解析一次
}

后端是容器或弹性伸缩时,IP 变了 Nginx 不知道,会持续往旧 IP 发请求,表现就是间歇性 502。改用变量加 resolver 可以强制每次解析:

resolver 10.0.0.2 valid=10s;
set $backend "api.internal:8080";
proxy_pass http://$backend;

注意用了变量之后,upstream 块里的 keepalive、权重这些就不生效了,需要自己在 proxy_http_version 1.1 和 proxy_set_header Connection "" 上补回来。

3. keepalive 没配,端口被 TIME_WAIT 占满

upstream backend {
    server 10.0.1.10:8080;
    keepalive 64;
}

keepalive 要生效,必须同时设置 proxy_http_version 1.1 并清掉 Connection 头,否则 Nginx 仍然每个请求新建连接。高 QPS 下这会迅速堆出大量 TIME_WAIT,ss -s 里 timewait 数量飙升的同时 502 开始出现,就是这个原因。

4. 缓冲区太小导致上游被提前中断

proxy_buffer_size       16k;
proxy_buffers           8 8k;
proxy_busy_buffers_size 16k;

上游响应头超过 proxy_buffer_size 时,Nginx 会把响应落到临时文件;如果 proxy_max_temp_file_size 为 0 且缓冲区不够,连接会被中断,日志里同样是 prematurely closed connection。响应头特别大的场景(大量 Set-Cookie)值得先怀疑这里。

四、worker 连接数不够也会报 502

grep -i 'worker_connections' /etc/nginx/nginx.conf
grep -c '^worker_processes' /etc/nginx/nginx.conf

worker_connections 是单个 worker 能同时处理的连接数,一个客户端连接会占用两个(前端 + 上游)。日志里出现 worker_connections are not enough 时,调大这个值比调超时有用得多。同时确认 ulimit -n 不低于这个配置,否则改了也不生效。

五、验证顺序

改完配置不要只看接口返回,按这三步确认:

nginx -t                      # 语法
nginx -s reload               # 平滑生效
curl -o /dev/null -s -w '%{http_code} %{time_total}\n' https://example.com/api/health

time_total 接近配置的超时值,说明上游确实慢,属于容量问题而不是配置问题;time_total 很短但仍是 502,说明连接阶段就失败了,回头查监听地址和健康检查。

最后一点:502/504 在网关层看是同一个现象,在日志里是完全不同的原因。先按错误措辞分类,再逐层确认连接是否建立、请求是否到达应用,比反复调整超时参数有效。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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