“upstream timed out”是现象而非根因,需结合错误后缀锁定卡点阶段(如connecting/reading header/prematurely closed),配合$upstream_connect_time与$upstream_header_time耗时、$request_time与$upstream_response_time对比、tcpdump抓包及nc实测,精准区分网络层、Nginx侧或后端业务瓶颈。

看到 upstream timed out,别急着调大超时值——它只是现象,不是根因。真正要查的是“在哪卡住”和“为什么卡”,尤其当常规调参无效、后端响应实际很快时,问题往往藏在底层网络链路里。
先锁定超时发生的精确阶段
错误日志括号里的描述是第一线索,直接决定排查方向:
-
while connecting to upstream:TCP 三次握手失败。重点查 SYN 是否发出去、有没有 ACK 回来。可能原因包括后端服务未监听、防火墙拦截、路由不可达、或上游 accept 队列溢出(
ss -lnt | grep :端口中 Recv-Q 持续 ≥ Send-Q); - while reading response header from upstream:连接已建好,但迟迟收不到第一个字节(HTTP 状态行)。说明请求已送达后端,但业务逻辑卡在数据库锁、远程调用、磁盘 I/O 或 CPU 调度上;
- upstream prematurely closed connection:后端主动断开了连接。常见于 PHP-FPM ondemand 模式回收进程、Spring Boot 默认 60s idle timeout 与 Nginx keepalive 不匹配,或中间 LB(如云厂商 ELB)静默关闭空闲连接。
用工具实测链路连通性与延迟
日志只能告诉你“超时了”,工具才能告诉你“卡在哪一跳”:
- 用
nc -zv 后端IP 端口快速验证基础连通性和端口可达性; - 用
tcpdump -i any host 后端IP and port 端口 -w timeout.pcap抓包,过滤出对应请求的 TCP 流,看是否有 SYN 重传、RST 包、或 ACK 延迟; - 用
mtr -r -c 50 后端IP查中间跳点丢包率和延迟突增位置(尤其注意云环境中的 NAT 网关、安全组、SLB); - 若使用 Kubernetes 或 Service Mesh,检查 Istio Sidecar、CNI 插件日志,确认是否因策略限流或 mTLS 握手失败导致连接阻塞。
对比耗时字段,分离 Nginx 侧与后端侧延迟
确保 access_log 中启用了关键变量:
- $upstream_connect_time 高 → 网络层或后端接入层问题(DNS 解析慢、SYN 重传、防火墙策略);
- $upstream_header_time 高(但 $upstream_connect_time 正常)→ 请求已到后端,但业务没及时返回响应头,需查后端线程阻塞、慢 SQL、锁竞争;
- $request_time 远大于 $upstream_response_time → 延迟在 Nginx 本体:可能是 rewrite 循环、大量 subrequest、SSL 握手耗时高,或 gzip 压缩大响应体卡住;
-
两者都高且接近 → 后端整体吞吐不足,查 CPU 负载、内存 OOM、文件描述符耗尽、或 jbd2 等内核级 I/O 卡顿(
iotop和top中 wa% > 90% 是典型信号)。
检查连接复用与中间设备兼容性
高频短请求下,反复建连会放大网络抖动影响:
- 确认 upstream 块启用
keepalive 32,location 中配套proxy_http_version 1.1和proxy_set_header Connection ''; - 用
ss -tn state established | grep :后端端口观察 ESTAB 连接数是否稳定,而非频繁新建/关闭; - 若后端是云服务(如阿里云 SLB、腾讯云 CLB),确认其空闲连接超时设置(通常 4–60 分钟),必须大于 Nginx 的
keepalive_timeout和后端自身 idle timeout; - 禁用中间设备的“TCP 优化”或“连接跟踪加速”功能,某些硬件网闸或 SD-WAN 设备会在无数据时强制中断长连接,导致 Nginx 复用失效后报 timeout。


















