nginx复用后端tcp连接需协议、请求头、连接池三者严格对齐:upstream中配置keepalive n,location中设proxy_http_version 1.1和proxy_set_header connection "",并合理设置keepalive_timeout与keepalive_requests。

要让 Nginx 真正复用与后端的 TCP 连接,不是加一行 keepalive 32 就完事,而是必须让协议、请求头、连接池三者严格对齐。漏掉任意一项,Nginx 仍会不断新建短连接,导致后端 TIME_WAIT 暴增、延迟升高、资源浪费。
upstream 块中正确声明 keepalive
该指令只能写在 upstream 块内,且必须位于 http 块下,不能放在 server 或 location 中,否则启动报错:unknown directive "keepalive"。
-
keepalive N表示每个 worker 进程对每台后端服务器最多缓存 N 个空闲长连接 - 若你有 4 个 worker、2 台后端,理论最大空闲连接数为
4 × 2 × N - N 值需匹配后端承载力:例如 Tomcat
maxConnections=200,按 70% 安全水位算,单 worker 建议设 32~48;轻量服务(如 Node.js)可从 16~32 起步 - 值不是越大越好——后端连接池太小(如 Go 默认
MaxIdleConnsPerHost=2),Nginx 设再大也连不上;后端不限制却设过高,可能耗尽其文件描述符
location 中强制启用 HTTP/1.1 并清空 Connection 头
Nginx 默认向上游发 HTTP/1.0 请求,而 HTTP/1.0 不支持连接复用。仅配 keepalive 不生效。
- 在
location块中添加proxy_http_version 1.1; - 同时添加
proxy_set_header Connection "";(注意是空字符串,不是"keep-alive") - 不要手动加
Keep-Alive头,Nginx 会自动处理 - 若后端返回
Connection: close(常见于错误响应或 WAF 干预),该连接立即释放,无法复用
控制空闲连接生命周期:keepalive_timeout 与 keepalive_requests
这两个参数从 Nginx 1.15.3+ 开始才对 upstream 生效,老版本(如 1.12)只认 keepalive,不支持超时与请求数限制。
-
keepalive_timeout 20s;:空闲连接在池中最多保留 20 秒;建议比后端空闲超时(如 Tomcat 的connectionTimeout)小 5~10 秒,避免持有已失效连接 -
keepalive_requests 500;:单个空闲连接最多转发 500 次请求后主动关闭,防止后端状态泄漏或内存堆积;默认 100 过于保守,API 场景推荐 500~1000
验证是否真正生效
配置写完不等于跑通,必须实测确认:
- 执行
ss -tnp | grep :8080 | grep ESTAB | wc -l(替换为你的后端端口),观察连接数是否稳定在预期值附近,而非持续增长或剧烈波动 - 压测对比开启前后:后端
TIME_WAIT数量、P95 延迟、建连耗时 - 检查后端响应头是否含
Connection: keep-alive;若返回close或缺失,说明后端未配合或中间设备干扰











