要让 Nginx 与后端服务复用 TCP 连接,必须同时配置 upstream keepalive、proxy_http_version 1.1 和 proxy_set_header Connection "",三者缺一不可:keepalive 启用连接池,HTTP/1.1 启用长连接语义,清空 Connection 头避免透传干扰。

要让 Nginx 与后端服务之间复用 TCP 连接,关键不是单纯加 proxy_set_header Connection "",而是它必须和 upstream keepalive、proxy_http_version 1.1 三者协同生效。单独设置 Connection 头清空,只解决“不主动断连”的问题,但无法建立连接池;没有 keepalive 指令,Nginx 就不会缓存空闲连接;不用 HTTP/1.1,后端根本不会识别 Keep-Alive 语义。
必须配齐的三个核心配置项
这三项缺一不可,且必须出现在对应作用域(upstream 块 + location 块):
-
upstream 中定义 keepalive N:例如
keepalive 32;,表示每个 worker 进程最多缓存 32 个空闲长连接供复用(注意:不是预创建,是“用完不关、留着再用”) -
location 中启用 HTTP/1.1:写
proxy_http_version 1.1;,强制 Nginx 向后端发起 HTTP/1.1 请求;HTTP/1.0 默认无 Keep-Alive,即使加 Connection 头也无效 -
location 中清空 Connection 请求头:写
proxy_set_header Connection "";,目的是删除客户端传来的Connection: close或其他干扰值,避免透传给后端导致误判为短连接
常见错误配置及后果
这些写法看似接近,实际无法开启 upstream 长连接:
- 只写
keepalive 32;,但没配proxy_http_version 1.1→ Nginx 默认用 HTTP/1.0 转发,后端响应后立即关闭,keepalive 形同虚设 - 写了
proxy_http_version 1.1,但漏掉proxy_set_header Connection ""→ 客户端带Connection: close时,Nginx 会原样转发,后端收到就断连 - 在
proxy_pass直接写 IP(如proxy_pass http://192.168.1.10:8080),未定义 upstream →keepalive指令不生效,Nginx 不支持对非 upstream 的 proxy_pass 启用长连接池
配套建议与验证要点
配置完成后,还需关注几个实际运行细节:
-
后端响应头必须含
Connection: keep-alive,且不能被 WAF、LB 等中间设备删改;可用curl -v查看后端原始响应确认 -
每个 upstream server 独立维护连接池:若 DNS 解析出 4 个后端 IP,总连接数 ≈
keepalive × 4,设过大可能耗尽上游端口或触发 TIME_WAIT 堆积 -
日志中可观察复用效果:启用
$upstream_addr和$upstream_response_time,同一 IP+端口反复出现、且响应时间稳定偏低,说明连接在复用 -
不需要手动加
Keep-Alive头:那是客户端行为,Nginx 作为代理不生成该头,也不应设置proxy_set_header Keep-Alive
一个可直接参考的最小完整配置
以下配置已通过生产验证,适用于大多数 HTTP/1.1 后端(如 Tomcat、Node.js、Gunicorn):
upstream backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
keepalive 32;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}











