502表示网关连接上游失败或收到无效响应,如“connection refused”;504表示网关已连上但等待响应超时,如“upstream timed out”。二者需结合trace-id、上下游日志及超时配置逐层定位。

502 和 504 都是网关层返回的错误,但它们指向完全不同的故障环节。在分布式系统中,错误不能只停留在 Nginx 日志里,必须能顺着调用链向后传递、定位、收敛——否则一个 502 可能掩盖了下游服务的线程阻塞,一次 504 可能被误判为网络问题,实则源于数据库连接池耗尽。
先分清错误类型:不是超时就是连接失败
502 Bad Gateway 的本质是“Nginx 发出了请求,但没收到合法响应”;504 Gateway Timeout 是“Nginx 连上了,但等太久,主动断开”。二者日志特征鲜明:
-
502 常见日志:
connect() failed (111: Connection refused)(上游没监听端口)、upstream prematurely closed connection(后端进程崩溃或主动断连) -
504 常见日志:
upstream timed out (110: Connection timed out) while reading response header from upstream(已建连,但响应头迟迟不来)
检查 Nginx 到上游的三层通信状态
分布式系统中,Nginx 往往不直连最终服务,而是经由服务发现(如 Consul、Nacos)或另一层网关(如 Spring Cloud Gateway)。排查要穿透这层抽象:
- 用
curl -v http://upstream-ip:port/health绕过 Nginx 直连目标实例,确认服务是否真实可达、健康接口是否返回 200 - 查 Nginx 所在节点的 DNS 解析是否准确:
nslookup upstream-service-name,避免因服务注册延迟导致解析到下线 IP - 确认上游服务绑定的是
0.0.0.0而非127.0.0.1,尤其在容器或 Kubernetes 环境中,localhost 会指向容器自身而非宿主机
配置参数需与下游链路节奏对齐
单点 Nginx 的超时设置,必须匹配整个调用链中最慢一环的预期耗时。比如 AI 推理服务平均响应 8 秒,但 Nginx 默认 proxy_read_timeout 60s 看似够用,若下游还有 gRPC 服务再调用模型服务,而该 gRPC 客户端设置了 10 秒 deadline,那 Nginx 等满 60 秒毫无意义——实际在第 10 秒就被下游切断了。
-
proxy_connect_timeout应略大于服务发现刷新周期(如 Consul health check interval + 网络 RTT) -
proxy_read_timeout不宜盲目拉长,建议设为下游最长 SLA 的 1.2~1.5 倍,并配合应用层熔断(如 Hystrix 或 resilience4j)提前失败 - 若链路含多级代理(Nginx → API Gateway → Service),各级超时应逐级递减,避免上级等待时间长于下级 deadline 导致“幽灵请求”堆积
让超时可追踪、可归因
生产环境不能只靠状态码和日志关键词判断问题。要在请求中注入唯一 trace-id,并确保它贯穿 Nginx、网关、业务服务、数据库:
- Nginx 中用
log_format记录$request_id和$upstream_response_time,便于关联上下游日志 - 在
location块中添加proxy_set_header X-Request-ID $request_id;,将 ID 透传给后端 - 当出现 504 时,结合
upstream_response_time=59.892和后端服务该 trace-id 的日志,能明确是卡在 DB 查询、外部 HTTP 调用,还是 GC 暂停











