504是nginx等网关主动返回的超时错误,非后端直接报错;排查需先定位“谁在等”(哪层超时),再查“为何等不到”(后端卡死、参数不匹配、资源不足或网络干扰)。

504 不是后端报的错,而是 Nginx 自己等不及了主动返回的。排查核心就一条:先确认“谁在等”、再查“为什么等不到”。别一上来就调大 timeout,那只是把问题藏得更深。
第一步:确认 504 真正发生在哪一跳
常见链路是:客户端 → CDN/负载均衡 → Nginx → PHP-FPM/Java 应用 → 数据库或第三方服务。504 可能出现在任意中间层,不能默认就是 Nginx 或后端的问题。
- 用 curl -v 带完整请求头 直接访问 Nginx 服务器 IP(绕过 CDN 和负载均衡),看是否还出现 504;如果没了,问题大概率在上游网关层
- 检查 Nginx 访问日志(access.log)里对应请求有没有记录;如果没有,说明请求根本没到 Nginx,卡在更前面
- 如果有记录,再查 error.log,重点找包含 "upstream timed out" 的行,它会明确告诉你超时类型(connect / read / send)和上游地址
第二步:看 Nginx 和后端之间的通信参数是否匹配
Nginx 的 timeout 设置必须大于后端实际处理耗时,且要和后端服务自身的超时机制对齐。比如用 fastcgi_pass 转发给 PHP-FPM,光调 Nginx 没用,PHP-FPM 自己也可能提前 kill 进程。
- 检查 Nginx 配置中对应 location 的超时项:fastcgi_read_timeout(PHP 场景)或 proxy_read_timeout(Java/Node 场景),建议设为后端平均响应时间的 1.5–2 倍,但不要盲目设成 3600
- 同步检查 PHP-FPM 配置:request_terminate_timeout 和 request_slowlog_timeout,确保它不比 Nginx 的 read_timeout 更短
- 若用 proxy_pass,还要留意 proxy_connect_timeout(建连)、proxy_send_timeout(发请求)、proxy_read_timeout(等响应)三者分工不同,不能只改一个
第三步:验证后端是否真在处理,还是已卡死或假死
504 表面是“等不到响应”,但背后可能是后端进程僵死、数据库锁表、连接池耗尽、外部 API 彻底无响应等深层问题。
- 在出问题时段,登录服务器执行 ss -tnp | grep :端口 或 netstat -anp | grep php-fpm,观察连接数是否堆积、ESTABLISHED 是否异常多
- 查 PHP-FPM 的 slow log(需提前开启),看是否有某类请求长期卡在某个函数或 SQL 上
- 用 mysqladmin proc 或 show processlist 查 MySQL 是否有长时间 Running 或 Waiting for table metadata lock 的线程
- 临时用 curl -v http://127.0.0.1:端口/健康检查路径 直连后端服务,确认它本身能及时响应
第四步:排除网络与资源干扰
有时不是代码慢,而是基础设施拖了后腿。
- 检查 Nginx 与后端服务是否跨网段或跨可用区,ping 和 telnet 测试延迟与端口连通性
- 运行 top 和 free -h,确认服务器没有 CPU 打满、内存 OOM 或 swap 频繁使用
- 查看 dmesg 日志,确认是否因内核参数(如 net.ipv4.ip_local_port_range)不足导致连接失败,被误判为超时
- 如果用了容器或云环境,确认安全组、网络 ACL、WAF 规则没有静默丢包或限速











