必须同时配置upstream keepalive、proxy_http_version 1.1和proxy_set_header Connection ''三者,缺一不可;keepalive_timeout仅控制客户端连接,对后端复用无效,真正决定后端TCP连接复用的是这三项协同配置。

keepalive_timeout 本身不保证后端服务连接复用——它只控制 Nginx 与客户端之间的空闲连接保持时间,对 Nginx 到后端(upstream)的连接复用完全无效。
真正决定后端连接能否复用的,是另一套独立配置:upstream keepalive + proxy_http_version 1.1 + proxy_set_header Connection ''。这三者缺一不可。
❌ 常见误解:以为调大 keepalive_timeout 就能提升后端复用率
这是典型混淆。keepalive_timeout 放在 http、server 或 location 块里,只影响浏览器 → Nginx 这一段:
- 设为
60s:Nginx 等客户端 60 秒没新请求就关掉连接; - 它不触发、不维持、也不管理 Nginx → 后端的任何连接;
- 即使你设成
300s,后端连接该断还是断,复用率不会因此上升。
✅ 真正保障后端连接复用的三项硬性配置
必须同时满足以下条件,Nginx 才会复用到后端的 TCP 连接:
-
upstream 块中启用连接池
upstream backend { server 10.0.2.8:9000; keepalive 32; # 每个 worker 进程最多缓存 32 个空闲连接到该后端 } -
强制使用 HTTP/1.1 协议转发
在location或server块中添加:proxy_http_version 1.1;
-
清空客户端传来的 Connection 头
避免Connection: close被透传给后端,导致后端主动断连:proxy_set_header Connection "";
⚠️ 注意:
keepalive 32必须写在upstream块内,写在location里会报错unknown directive "keepalive"。
? 补充关键参数(作用于 upstream 连接池)
虽然 keepalive_timeout 不管后端,但 upstream 层有自己的一组生命周期参数(Nginx 1.15.3+ 支持):
keepalive_timeout 20s;
→ 每个空闲连接在连接池中最多保留 20 秒(注意:这是 upstream 的 timeout,不是 http 块里的那个!必须写在 upstream 块内或 location 中配合 proxy_pass)
建议值比后端服务的空闲超时小 5–10 秒(例如 Tomcat 设connectionTimeout="-1"且keepAliveTimeout=60000,则此处设55s)。keepalive_requests 1000;
→ 单个长连接最多转发 1000 次请求,避免连接长期霸占资源或因缓冲区老化出错。
? 怎么确认后端连接真的复用了?
别只看配置有没有写,用实际指标验证:
-
查当前 ESTABLISHED 连接数(目标后端端口):
ss -tan | grep :8080 | grep ESTAB | wc -l
压测中应稳定在
worker_processes × keepalive附近,而不是随 QPS 线性上涨。 抓包观察:多个请求是否复用同一源端口 → 目标端口组合(如
192.168.1.100:42321 → 10.0.2.8:9000)。-
检查后端
TIME_WAIT数量是否明显下降:ss -s | grep -i time_wait
查 Nginx error log:若频繁出现
upstream prematurely closed connection,说明后端提前断连,复用失败。
不复杂但容易忽略



















