问题在于nginx与后端连接管理不当,非业务耗时所致;需优化keepalive连接池、分级设置connect/send/read超时、对齐后端空闲超时并启用健康检查。

nginx 报 upstream timed out,但后端实际响应很快,说明问题不在业务处理耗时,而在于 nginx 与后端建立连接、发送请求或读取响应的过程被阻塞或等待过久。常见原因集中在连接池复用不足、超时设置不合理、网络中间件干扰或后端主动关闭空闲连接。调优需从连接管理、超时分级、健康检查三方面入手。
连接池:避免频繁建连与端口耗尽
默认情况下,nginx 对每个 upstream server 维护的 keepalive 连接数极少(甚至为 0),导致每次请求都新建 TCP 连接,易触发 SYN 重传、TIME_WAIT 堆积或内核端口不足,间接表现为“超时”。
-
启用并合理配置 keepalive:在 upstream 块中添加
keepalive 32;(建议 16–256,视并发量调整),它表示 nginx 与单个后端保持的空闲长连接数; -
配套设置 proxy_http_version 和 Connection 头:在 location 中加
proxy_http_version 1.1;和proxy_set_header Connection '';,确保复用连接不被后端误关闭; - 注意 keepalive 不是最大连接数:它只控制空闲连接池大小,活跃连接仍可超出该值;若后端有连接数限制(如 Tomcat maxConnections),需确保 nginx keepalive 数 × 并发上游数 ≤ 后端承载能力。
超时参数必须分级设置,不能只调 proxy_read_timeout
“upstream timed out” 错误日志中通常会注明具体阶段,例如 while connecting to upstream 或 while reading response header from upstream,对应不同超时项。仅加大 proxy_read_timeout 无法解决连接建立慢的问题。
- connect_timeout:控制 nginx 与后端建立 TCP 连接的最长等待时间,默认 60s,高负载或跨机房场景建议设为 3–5s;
- send_timeout:两次写操作之间的间隔上限(非整个请求发送耗时),默认 60s,一般无需调整,除非后端流式推送极慢;
- read_timeout:从后端读取响应头或数据的超时间隔,建议设为 10–30s,避免因后端偶发卡顿拖垮整个连接池;
-
关键点:所有 timeout 值应明显小于客户端的
client_header_timeout和client_body_timeout,防止 nginx 卡在上游时客户端已断开,造成连接堆积。
后端兼容性与健康检查联动优化
即使后端响应快,若其主动关闭了 nginx 认为“可用”的空闲连接(如 Spring Boot 默认 60s idle timeout),nginx 下次复用该连接时会遇到 connection reset,继而重试或报超时。此时需对齐两端空闲策略,并启用主动健康检查。
- 对齐 keepalive timeout:将后端 Web 容器(如 Nginx、Tomcat、Gunicorn)的 keepalive_timeout 设为 ≥ nginx 的 keepalive 超时(如 nginx keepalive 30s,则后端设为 45s);
- 启用 active health check(nginx Plus 或开源版 1.11.5+ with http_upstream_check_module):定期探测后端连接可用性,及时摘除已失效的 keepalive 连接;
-
无健康检查模块时,可降级使用 proxy_next_upstream:添加
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;并配合proxy_next_upstream_tries 3;,提升容错性,但不解决根本连接陈旧问题。
验证与观测建议
调优后需结合日志和指标确认效果:
- 开启 nginx
error_log ... debug;(临时),搜索upstream connect、upstream send、upstream recv等关键词,定位超时发生阶段; - 监控
nginx_stub_status中Active connections与Reading/Writing/Waiting分布,若 Waiting 长期偏高,可能 client 端慢或 upstream 响应头延迟; - 用
ss -tan | grep :观察 nginx 到后端的 ESTABLISHED 连接数是否稳定在 keepalive 设置范围内;| wc -l - 抓包验证(如
tcpdump -i any port)看是否存在 RST、重传或 FIN 早于响应的情况。and host










