Nginx中504和499超时报错的原因排查与解决完整方案

 更新时间:2026年10月28日 09:10:16   作者:Initialize-le  
还在为Nginx 504或499超时头疼吗,本文将系统解析Nginx中504 Gateway Time-out与499客户端主动断连的本质区别并提出四步定位法,有需要的小伙伴可以参考下

页面转圈十几秒,最后甩出「504 Gateway Time-out」;打开访问日志,又发现一排没人认识的 499。两个都像是"超时",但锅不在同一个人身上。这篇把 504 和 499 拆开,用四步定位到真正的慢点。

一、先分清 504 和 499 分别在说谁

很多人把这两个码混着看,结果越查越乱。区别其实很干脆:

  • 504 Gateway Time-out:Nginx 把请求转给后端后,等不到响应就放弃了。锅在后端或链路慢——后端还在处理,只是超过了 Nginx 的等待上限。
  • 499:Nginx 自己发明的非标准码(Nginx 日志里才有,HTTP 标准里没有),含义是 client closed request——请求还没返回,客户端先断开连接了。锅常常在"客户端等不及",而它等不及的原因,往往又是后端真的慢。

所以线上常见的一幕是:后端慢 → 客户端(或上游负载均衡、手机 App)先超时断开 → Nginx 记一条 499;如果客户端够有耐心等到 Nginx 自己超时,那就是 504。

结论:504 和 499 经常是同一个病根的两个表现,别当成两个独立故障查。

二、第 1 步:让日志说出"到底谁慢"

默认的 access log 看不出时间花在哪,先把三个时间字段加进 log_format:

log_format timed '$remote_addr $request '
                 'rt=$request_time '
                 'urt=$upstream_response_time '
                 'us=$upstream_status '
                 'ua=$upstream_addr '
                 'st=$status';

access_log /var/log/nginx/access.log timed;

四个字段是排查的核心:

  • $request_time:Nginx 从收到第一个字节到发完响应的总耗时;
  • $upstream_response_time:Nginx 发给后端、到收完后端响应的时间;
  • $upstream_status:后端返回的状态码(可能多个,用逗号分隔,对应多次重试);
  • $upstream_addr:真正处理这次请求的后端地址(多实例时能定位到具体那台)。

reload 之后,用两行 awk 就能把慢请求捞出来:

# 按 upstream 耗时排序,看最慢的 20 条
awk -F'urt=' '{split($2,a," "); print a[1], $0}' access.log | sort -rn | head -20

# 统计 504/499 出现的频次与对应后端
grep -E ' (504|499) ' access.log | awk '{print $NF, $(NF-3)}' | sort | uniq -c | sort -rn

判读原则很直接:

  • rt 很大、urt 也很大 → 慢在后端,继续查后端;
  • rt 很大但 urt 很小甚至为 - → 慢在 Nginx 或客户端这一侧(大响应体、慢客户端、带宽打满)。

三、第 2 步:确认是"后端超时"还是"连接就不通"

看 error.log 的关键字,能一次分辨两种性质完全不同的 504:

grep -i 'upstream timed out' /var/log/nginx/error.log | tail -20
  • upstream timed out (110: Connection timed out) while reading response header from upstream→ 连上了后端,但后端迟迟不吐响应头。这是后端处理慢,最常见。
  • upstream timed out (110: ...) while connecting to upstream→ 连后端都连不上。这是网络或后端端口问题,不是慢,是通不通。
  • no live upstreams / connect() failed (111: Connection refused)→ 后端进程挂了或连接池被打满。

紧接着核对生效的超时配置:

nginx -T | grep -E 'proxy_(connect|send|read)_timeout|keepalive'

三个超时的分工要分清:

指令管的是什么
proxy_connect_timeout与后端建立连接的等待上限
proxy_send_timeout向后端发送请求的两次写操作间隔上限
proxy_read_timeout等待后端返回响应的两次读操作间隔上限(504 最常撞的就是它)

四、第 3 步:直连后端,把 Nginx 摘出去

怀疑是 Nginx 就先绕开它。在 Nginx 机器上直连后端端口,用 curl 把耗时分段打出来:

curl -o /dev/null -s -w 'dns=%{time_namelookup} conn=%{time_connect} ttfb=%{time_starttransfer} total=%{time_total}\n' \
     http://10.0.0.12:8080/api/health
  • time_connect 就很大 → DNS 或 TCP 建连慢(网络层);
  • time_starttransfer(TTFB)大 → 后端处理慢(应用层);
  • total 远大于 ttfb → 响应体传输慢(带宽 / 大文件)。

**直连也是几十秒没响应 → 问题在后端,别在 Nginx 上折腾了。**这一步能省掉一半无效排查。

五、第 4 步:五类根因速查

  1. 后端自身慢:慢 SQL、Full GC、下游接口拖累、锁等待。表现为 urt 持续偏大,504 集中在某些接口上($request 能看出规律)。
  2. 后端排队:worker 进程数不够、线程池 / 连接池打满,请求在 backlog 里排队。表现为并发一上来才超时,平时正常。
  3. Nginx 到后端的 keepalive 没配:每个请求都重新建连,高并发下建连耗时叠加成超时。需要 upstream 里加 keepalive 64;,同时 proxy_http_version 1.1; + proxy_set_header Connection "";,三者缺一不可。
  4. 长任务同步等待:数据导出、报表生成、大文件下载硬等几十秒。这类请求本就不该同步等,应该改成异步任务 + 轮询/回调。
  5. 超时阈值配反了:客户端超时 < Nginx 超时 < 后端超时。任何一层率先放弃,就会记成 499 或 504。正确顺序是:客户端 > Nginx > 后端应用,让最早发现问题的层来报错。

六、避坑清单

  1. 只调大 proxy_read_timeout 是掩盖,不是解决——请求继续堆积,连接数、内存一起涨,只是爆炸时间往后推。
  2. proxy_read_timeout 要大于后端应用自身的超时,否则后端还在等下游,Nginx 已经先甩 504 了,日志里只剩一句超时。
  3. 504 和 499 别混着下结论:499 通常意味着客户端先走人,检查前端 axios / 网关 / SLB 的超时设置。
  4. 云负载均衡(SLB / ALB)也有空闲超时,通常比 Nginx 更短,客户端到 Nginx 这一段先在 SLB 断掉,Nginx 日志里就是 499。
  5. upstream_status 是逗号分隔的多个值时,说明发生了重试,每个值对应 upstream_addr 里的一个后端,能直接看出是哪台在拖后腿。
  6. 不要把 ping 当证据:ICMP 通不代表 8080 端口通,也不代表后端应用没卡死。
  7. 两次采样之间要看趋势:偶发 504 去查后端 GC 与慢查询;持续 504 先查后端进程/线程池是否已经饱和。

小结

排查顺序记成一句话:先看 access log 的 $request_time / $upstream_response_time 分清慢在谁身上 → 读 error.log 的 upstream timed out 关键字区分"慢"还是"不通" → 直连后端端口复现,把 Nginx 摘出去 → 按"后端慢 / 排队 / keepalive / 长任务 / 阈值配反"五类根因对症处理。超时从来不是 Nginx 的错,它只是第一个把问题喊出声的人。

到此这篇关于Nginx中504和499超时报错的原因排查与解决完整方案的文章就介绍到这了,更多相关Nginx 504和499超时内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Nginx端口被占用的解决方案(systemctl restart nginx失败)

    Nginx端口被占用的解决方案(systemctl restart nginx失败)

    ginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器,它也是一种轻量级的Web服务器,可以作为独立的服务器部署网站(类似Tomcat),本文给大家介绍了NGINX启动报错,端口被占用解决方案,需要的朋友可以参考下
    2024-10-10
  • nginx正向代理与反向代理详解

    nginx正向代理与反向代理详解

    本文给大家分享的是nginx实现正向代理和反向代理的具体方法配置以及不同的实例情况,非常的详细,希望大家能够喜欢
    2020-03-03
  • 教你在容器中使用nginx搭建上传下载的文件服务器

    教你在容器中使用nginx搭建上传下载的文件服务器

    这篇文章主要介绍了容器中使用nginx搭建支持上传下载的文件服务器,在这需要注意为了让nginx支持文件上传,需要下载并运行带有nginx-upload-module模块的容器,需要的朋友可以参考下
    2022-05-05
  • Nginx访问控制及安全配置文档详解

    Nginx访问控制及安全配置文档详解

    本文档介绍了Nginx服务的访问控制、密码认证及版本隐藏配置,适用于主流Linux系统,可直接复制使用,主要内容包括生成密码文件、配置访问控制和密码认证、隐藏Nginx版本号,以及相关注意事项和常见问题排查
    2026-05-05
  • 使用google-perftools优化nginx在高并发时的性能的教程(完整版)

    使用google-perftools优化nginx在高并发时的性能的教程(完整版)

    如果使用googler开发的google-perftools优化Nginx和MySQL的内存管理,性能将会有一定程度的提升。特别是对高并发下的服务器,效果更明显
    2013-02-02
  • 分享Nginx下10个安全问题提示

    分享Nginx下10个安全问题提示

    Nginx是当今最流行的Web服务器之一。它为世界上7%的web流量提供服务而且正在以惊人的速度增长。它是个让人惊奇的服务器,我愿意部署它
    2014-04-04
  • 详解Nginx如何配置Web服务器的示例代码

    详解Nginx如何配置Web服务器的示例代码

    这篇文章主要介绍了详解 Nginx如何配置Web服务器的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 详解nginx静态资源服务器简单配置

    详解nginx静态资源服务器简单配置

    这篇文章主要介绍了详解nginx静态资源服务器简单配置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 配置Nginx日志url encode问题及解决

    配置Nginx日志url encode问题及解决

    文章介绍了在Nginx中配置自定义日志输出格式,处理URL参数中文编码的问题,方法一是安装Lua模块并使用`escape=json`;方法二是安装`set-misc-nginx-module`模块,这两种方法均能解决中文输出为十六进制字符串的问题
    2026-05-05
  • Nginx基础location语法及功能配置实例

    Nginx基础location语法及功能配置实例

    这篇文章主要为大家介绍了Nginx基础location语法及功能以及配置实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03

最新评论