$upstream_status仅反映当前Nginx实例所连上游的状态码,要定位多级代理中具体哪层返回502,须每层独立记录layer-specific access_log并透传X-Upstream-L{N}-Status响应头,再结合error.log报错与curl分段验证交叉确认。

直接看 $upstream_status 本身不能跨层定位,它只反映当前 Nginx 实例所连接的那层上游返回的状态码。要追踪多级代理中具体哪一层吐出 502,必须让每一层 Nginx 都记录并透传自己的 $upstream_status 和 $upstream_addr,再逐层回溯。
每层 Nginx 必须独立记录本层 upstream 状态
不能依赖单点日志。每一级代理(比如网关层 → 服务层 → 数据层)都要配置专属 access_log 格式,显式包含本层关键变量:
- log_format layer1 '$remote_addr - [$time_local] "$request" $status $upstream_status $upstream_addr $upstream_response_time';
- log_format layer2 '$remote_addr - [$time_local] "$request" $status $upstream_status $upstream_addr $upstream_response_time';
- 各层启用对应格式:access_log /var/log/nginx/layer1.log layer1;
用响应头逐层透传上游状态,形成可追溯链路
仅靠日志时间对齐不可靠。应在每层 proxy_pass 后,把本层获取到的 upstream 状态和地址,通过自定义响应头向下游传递:
- 网关层(L1):proxy_set_header X-Upstream-L1-Status $upstream_status; proxy_set_header X-Upstream-L1-Addr $upstream_addr;
- 服务层(L2):接收 L1 的头,再添加自己的:proxy_set_header X-Upstream-L2-Status $upstream_status; proxy_set_header X-Upstream-L2-Addr $upstream_addr;
- 最终客户端或日志采集端,可通过完整响应头看到类似:X-Upstream-L1-Status: 200, X-Upstream-L2-Status: 502, X-Upstream-L3-Status: - ——说明问题出在第二层
结合 error.log 中的连接线索交叉判断
当某层 access.log 显示 $upstream_status 为 502,立刻查该层 error.log 中是否出现如下典型报错:
- upstream timed out (110: Connection timed out) → L2 连 L3 超时,L3 可能卡死或未监听
- no live upstreams while connecting to upstream → L2 的 upstream 组里所有节点都健康检查失败,L3 全挂或网络不通
- connection refused → L2 尝试连 L3 的 IP:Port 被拒,L3 进程未启动或端口错
用 curl 分段实测,快速隔离故障层级
拿到一个返回 502 的请求,按链路从外向内逐层 curl 验证:
- curl -v http://gateway/api/v1/user → 得 502 → 查 gateway 的 access.log 和 error.log
- 若 gateway 日志显示 $upstream_status=502 且 $upstream_addr=10.0.2.10:8080,则 curl -v http://10.0.2.10:8080/api/v1/user → 看是否真返回 502 或超时
- 若该请求成功,说明 gateway 日志里的 502 是误报(可能 proxy_next_upstream 触发重试后返回了 502),需检查 retry 策略











