Nginx 反向代理导致 504 网关超时,怎么解决?

Nginx 反代 504 Gateway Timeout 排查:proxy_read_timeout 等超时参数调优、上游应用慢在哪、长任务异步化、按 URI 分级超时配置与 FAQ。

最佳实践
Nginx 反向代理导致 504 网关超时,怎么解决?封面

504 的含义:Nginx 等上游(后端应用)的响应等超时了。 两条处置线并行:调大 Nginx 的代理超时参数治标;查清上游为什么慢治本。

治标:调大超时参数

location / {
    proxy_pass http://backend;

    proxy_connect_timeout 60s;    # 连上游的建立连接超时(默认 60s,一般够用)
    proxy_send_timeout    120s;   # 往上游写请求的超时
    proxy_read_timeout    120s;   # 等上游响应的超时(504 多半栽在这)
}

三个参数的分工:

指令 管哪段 默认值
proxy_connect_timeout TCP 连接上游的握手 60s
proxy_send_timeout 两次写操作之间的间隔 60s
proxy_read_timeout 两次读响应之间的间隔 60s

注意:read_timeout两次读到数据之间的间隔,不是整个响应的总时长——上游持续吐数据就不会触发。整个请求都很慢的"长任务",光调它不够。

治本:找出上游为什么慢

504 是症状,病根在上游:

# 上游还活着吗?
curl -v http://backend-ip:port/health

# 上游日志:请求到了吗?处理多久?
tail -f /var/log/app/app.log

高频病因:慢查询拖住接口、上游线程/连接池耗尽、上游自己又在等更下游的服务、应用 GC 停顿。

工程层面的正确解法

  • 长任务异步化:报表导出、批量处理这类秒级回不来的活儿,改成"提交任务→立即返回→轮询/Webhook 通知",别让人肉 HTTP 请求硬等。
  • 按 URI 分级超时:普通接口 30s,确实需要慢的接口单独 location 放宽,别全局调成 600s——那会掩盖真问题。
  • upstream 健康检查:某台后端卡住时把它摘出去,而不是让所有请求陪着超时。

观测云对照

504 的排查本质是回答"慢在哪一段"。观测云 APM 把一次请求在 Nginx → 应用 → 数据库的各段耗时串成完整 Trace,火焰图直接指出时间花在哪层;访问日志里的 $upstream_response_time$request_time 对比,一眼区分"上游慢"和"客户端网络慢";再对 504 比例、上游 P99 延迟设告警,超时恶化在投诉到来前就能发现。

常见问题(FAQ)

Q:调大 timeout 后变成 502 了?
A:说明上游进程在你等待期间挂了或主动断连(比如应用自己的超时更短,先掐了)。查上游的超时配置(如 Gunicorn 的 --timeout、PHP 的 max_execution_time),全链路要对齐。

Q:有些请求要跑 5 分钟,把 read_timeout 设 300s 合理吗?
A:技术上可行,工程上反对。5 分钟的同步请求占用连接、怕中间任何一环抖动,正确姿势是异步任务 + 通知机制。

Q:怎么区分 504 和 502?
A:504 = 上游活着但没按时回话;502 = 上游回了但内容非法/连接被断。error.log 里的文案分别是 upstream timed outupstream prematurely closed connection 等。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台