“upstream timed out”需结合超时阶段关键词和耗时变量判断:connecting 阶段异常多为网络问题,reading header/response 阶段异常多为业务过载;connect_time 偏高波动大指向网络层,header_time 延迟则提示后端处理瓶颈。

单看“upstream timed out”日志无法直接判断是网络抖动还是业务过载,必须结合多个变量和上下文交叉验证。核心思路是:网络问题主要影响连接建立与数据传输阶段,而业务过载集中在后端处理阶段——两者在日志中留下明显不同的时间特征和状态痕迹。
看错误日志中的超时阶段关键词
Nginx 错误日志里“upstream timed out”后面紧跟着的描述,直接指明了卡在哪一环:
- while connecting to upstream:TCP 连接未建立成功,大概率是网络层问题(如防火墙拦截、路由异常、后端进程未监听、SYN 重传失败),也可能是后端已崩溃或端口被占;
- while reading response header from upstream:连接已建好,请求也发过去了,但迟迟没收到响应头——这时要重点查后端是否卡在初始化、锁竞争、DB 查询阻塞或 GC 暂停;
- while reading response from upstream:响应头已收到,但响应体传输慢或中断,常见于后端流式输出卡顿、大文件生成慢、或中间网络丢包导致 TCP 重传延迟;
- while sending request to upstream:Nginx 向后端发请求时卡住,较少见,多与后端连接池耗尽、接收缓冲区满或反向代理自身 write 阻塞有关。
用 $upstream_connect_time 和 $upstream_header_time 组合判断
这两个变量记录了真实耗时,比单纯看 timeout 配置更有诊断价值:
- 若 $upstream_connect_time 明显偏高(>1s)且波动大,而 $upstream_header_time 正常(
- 若 $upstream_connect_time 很低(2s),说明连接快、处理慢,基本可锁定为业务逻辑阻塞(如慢 SQL、同步调用第三方、锁等待);
- 若两者都高且同步飙升,需检查后端整体资源(CPU、内存、线程数),可能已进入过载雪崩状态。
对照 $upstream_status 看重试行为是否频繁失败
$upstream_status 记录每次 upstream 尝试的真实状态码序列(如“504,502,200”),它能暴露“表面成功、背后抖动”的真相:
- 如果大量请求的 $upstream_status 是 空值或单个 200,但 error.log 里仍有 sporadic “upstream timed out”,说明超时发生在未触发重试的首次请求上——更倾向网络偶发故障;
- 如果 $upstream_status 中高频出现 逗号分隔的失败码(如“504,504,200”或“502,504,200”),说明 proxy_next_upstream 已生效且反复兜底,这是典型后端不稳信号:要么网络抖动导致部分请求失败,要么后端实例局部过载(如某 Pod CPU 100%);
- 注意:若 $upstream_status 几乎全是单个 504,且无重试痕迹,说明 proxy_next_upstream 未开启或配置未覆盖 timeout/error,此时不能归因为抖动,而是超时阈值设置不合理或后端完全不可达。
关联后端应用日志与系统指标交叉验证
日志本身只是线索,最终确认需横向比对:
- 查后端同一时间点的 GC 日志、慢查询日志、线程 dump:若发现 Full GC、长事务、BLOCKED 线程,则是业务过载;
- 看后端所在节点的 CPU、内存、load、网络重传率(RetransSegs):若 CPU 1%,大概率是网络抖动;
- 对比 Nginx 所在机器的 netstat -s | grep -i "retransmit":若本机 TCP 重传陡升,而下游后端监控平稳,说明问题在 Nginx 到后端链路中间(如 SLB、VPC 路由、安全组限速)。











