Nginx 499、502、504 分别是谁的问题:三段超时排查法
前端报「请求失败」,后端日志干干净净,运维打开 Nginx 的 error.log 只有一行 upstream timed out。这类问题的难点往往不在改配置,而在先判断到底是哪一段先放手。499、502、504 恰好对应请求链路上的三个不同角色,按顺序排一遍,多数争议能在十分钟内收敛。
一、三个状态码分别是谁写的
- 499 是 Nginx 独有的状态码(Client Closed Request),由 Nginx 自己写下:客户端在 Nginx 返回响应之前就关闭了连接。
- 502 表示 Nginx 已经连上上游,但上游返回的内容无法解析,或者上游直接拒绝、断开了连接。
- 504 表示 Nginx 连上并等待了上游,等到自己配置的上游超时,上游仍未把响应给完。
一句话结论:499 的责任在客户端或客户端到 Nginx 这一段;502、504 的责任在 Nginx 到上游这一段。502 是「拿到了但看不懂」,504 是「根本没拿到」。
二、先看 499 的分布,别急着调大超时
很多人一看到超时就去调大 proxy_read_timeout。如果问题主体是 499,这样做是无效的:499 的计时器根本不在 Nginx 等待上游的那一段里,而是客户端先不玩了。
# 统计当天各状态码出现的次数
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
499 集中在某个接口、某个时段,通常对应两种真实原因:一种是前端主动取消(切换页面、单页应用重新渲染时 abort 掉旧请求);另一种是客户端自己的超时比 Nginx 更短。后者最容易误判——前端 axios 设了 5 秒超时,而接口要 8 秒才返回,日志里就永远是 499,后端却「一切正常」。
三、504 要看的是哪一段超时
504 出现时,要先区分是 Nginx 等响应头超时,还是上游处理本身太慢。做法是给日志加上真实耗时字段,让两段耗时可以直接比较:
log_format upstream_time '$remote_addr - $request '
'status=$status upstream=$upstream_addr '
'rt=$request_time urt=$upstream_response_time';
request_time 是整个请求在 Nginx 内部的耗时,upstream_response_time 是 Nginx 到上游的往返耗时。两者差值就是 Nginx 自身和客户端往返的开销。如果 urt 已经贴着超时阈值,说明确实是上游慢,此时应该优化上游或做异步化;继续把 Nginx 超时调到 600 秒,只会让连接池被慢请求占满,把单点慢放大成雪崩。
四、502 先分清是「连不上」还是「断在半路」
502 的两种常见成因,看 error.log 的措辞就能区分:
- connect() failed (111: Connection refused):Nginx 根本没连上上游,问题在端口、进程存活或健康检查。
- upstream prematurely closed connection while reading response header:连上了,但上游自己先断开,常见于上游崩溃、OOM,或 keepalive 超时被对端先关。
grep -E 'connect\(\) failed|prematurely closed' /var/log/nginx/error.log | tail -20
五、把三段合成一张表
| 状态码 | 计时终点 | 常见真实原因 | 优先动作 |
|---|---|---|---|
| 499 | 客户端断开 | 前端取消、客户端超时更短 | 对齐前后端超时,查前端 abort |
| 502 | 上游连接或响应头 | 端口不通、上游崩溃、keepalive 被对端关闭 | 看 error.log 措辞,先查上游存活 |
| 504 | 上游响应超时 | 上游慢查询、依赖卡住 | 比较 urt 与 rt,优化上游 |
六、一个容易踩的坑
proxy_next_upstream 的默认值包含 error 和 timeout,但这不意味着对任何方法都能安全重试。对非幂等的 POST 请求做故障切换重试,可能造成重复写入。需要多上游切换时应当显式配置,并且只对幂等方法开启,或者依赖上游返回的状态码来区分。
结语
404 是谁的错一眼能看出来,499、502、504 不能。先确认状态码由谁写下,再看对应的时间字段,最后才动配置。顺序反过来,就容易陷入「调大超时—偶发变少—高峰期再炸」的循环。
- 点赞
- 收藏
- 关注作者
评论(0)