首页 > Technology > 正文

Nginx 504 网关超时:三步定位上游

fenij 2026-08-19 50 Technology

网站能打开,但接口迟迟不返回,最后页面甩出一句「504 Gateway Time-out」——这不是服务器挂了,而是 Nginx 等上游等累了。504 的本质是反向代理在约定时间内没收到后端响应,问题几乎永远出在「Nginx 与后端的超时配置」或「后端自己太慢、卡死」上。按下面三步,基本能定位八成以上的 504。

504 和 502,先别混为一谈

很多人把 502 和 504 当成一回事,其实排错方向完全不同。502 是上游「给了个无效响应」或「直接断了」;504 是上游「一直没给响应,超时了」。先分清,才不会在错误的方向上浪费时间。

错误码 含义 常见根因
502 上游无有效响应 PHP-FPM 进程崩了、上游服务挂掉
504 上游响应超时 后端慢查询、worker 耗尽、超时太短

三步定位上游卡点

顺着「Nginx 配置 → 后端进程 → 资源/网络」这个顺序查,最快。

1看 Nginx 错误日志

2直连后端端口

3查资源与慢请求
# 1. 看 Nginx 错误日志,确认是超时
tail -f /var/log/nginx/error.log
# 典型输出:
# upstream timed out (110: Connection timed out) \
#   while reading response header from upstream

# 2. 绕过 Nginx 直连后端,排除 Nginx 自身问题
curl -i http://127.0.0.1:8080/api/health

# 3. 看后端进程是否吃满 CPU / 内存
top -p $(pgrep -f "your-backend")

踩坑实录

上周一台 Docker 里的 Nginx 反代 PHP-FPM,接口偶发 504。我第一反应是调大 proxy_read_timeout 到 120s,结果没用。后来 docker logs 看到 PHP 日志里一条慢查询跑了 90 秒。根因是 FPM 的 pm.max_children 只有 5,并发一高请求就排队,前端直接等超时。把 children 调到 20、再给那条 SQL 加索引,504 消失。教训:504 往往不是 Nginx 的锅,是后端自己堵了。

常见根因与对策

后端慢查询
开慢日志,给高频 SQL 加索引,避免全表扫。

worker 耗尽
PHP-FPM pm.max_children 太小,请求排队超时。

超时太短
proxy_read_timeout 默认 60s,报表类需放宽。

后端 OOM
dmesg | grep oom 看是否被杀,加内存或限并发。

常见问题

proxy_read_timeout 设多大合适?
普通接口 60s 内够用;报表、导出、批量类可放宽到 300s,但别无限大,否则一个慢请求会拖垮整个连接池。

502 和 504 同时出现怎么排?
先按 502 的思路查上游是否还活着(直连端口、看进程),确认存活后再按 504 调超时和后端性能。

如果这篇帮你省了一次半夜告警,欢迎在 fenij.com 留言说说你踩过的 504 坑,或者推荐你想看的下一篇排障主题。

排错自查清单

  • ☐ 504 和 502,先别混为一谈:很多人把 502 和 504 当成一回事,其实排错方向完全不同。502 是上游「给了个无效响应」或「直接断了」
  • ☐ 三步定位上游卡点:顺着「Nginx 配置 → 后端进程 → 资源/网络」这个顺序查,最快。
  • ☐ 踩坑实录:上周一台 Docker 里的 Nginx 反代 PHP-FPM,接口偶发 504。我第一反应是调大 proxy
  • ☐ 常见根因与对策
  • ☐ 常见问题:proxy_read_timeout 设多大合适?普通接口 60s 内够用;报表、导出、批量类可放宽到 300

关键命令速查

  • # 1. 看 Nginx 错误日志,确认是超时 tail -f /var/log/nginx/error.log # 典型输出: # upstream timed out (110

相关延伸

更系统的排查思路,见 Technology 分类归档

补充:504 是「上游太慢或已死」,和 502(上游直接拒绝)要分开看。先调大 proxy_read_timeout 试水,同时查 PHP-FPM 的 max_children 是否打满。Nginx 与后端超时务必对齐,否则两边都超时反而更难查;慢接口建议上缓存或异步,别靠无限拉超时硬扛。也别忽略资源配额:K8s 里 requests/limits 设太低会被调度器 OOMKilled,看 Events 里的 OOMKilled 关键词就能判断是内存不够还是真崩溃。

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: