单靠一行keepalive不能降低后端TCP握手开销;必须同时配置proxy_http_version 1.1、proxy_set_header Connection ""和upstream keepalive N,三者缺一不可,并合理设置keepalive_requests、keepalive_timeout及proxy_socket_keepalive,且后端需兼容长连接。

靠单加一行 keepalive 不能降低后端 TCP 握手开销。真正起效的前提是让 Nginx 复用与后端的已有连接,这需要协议、头部、连接池三者严格协同,缺一不可。
必须配齐三项基础配置
只在 upstream 块里写 keepalive 64; 是无效的:
-
启用 HTTP/1.1 协议转发:在
location或server块中添加proxy_http_version 1.1;。HTTP/1.0 默认关闭长连接,Nginx 不会尝试复用。 -
清空 Connection 请求头:添加
proxy_set_header Connection "";。否则 Nginx 可能继承客户端传来的Connection: close,导致后端主动断连。 -
声明空闲连接池大小:在
upstream块内设置keepalive N;(如keepalive 64;),表示每个 worker 进程为该 upstream 缓存最多 N 个空闲连接。
合理设置 keepalive 参数组合
单靠一个数值不够,建议搭配使用:
keepalive 32–128</strong></li> <li><strong><code>keepalive_requests 500</strong></li> <li><strong><code>keepalive_timeout 15–30s</strong></li> </ul> <H3>补充 socket 层保活防静默断连</H3> <p>公网或 CDN 回源场景下,中间设备可能悄无声息地切断空闲连接:</p> <ul> <li>添加 <code>proxy_socket_keepalive on 60s 5s 3;
:空闲 60 秒后开始探测,每 5 秒发一次心跳,连续 3 次无响应则关闭 socket。- 该指令作用于 upstream 连接池中的每个 socket,与 HTTP 的
Connection: keep-alive无关,专治“连接还在但实际已断”的问题。
确认后端服务兼容 keepalive
上游连接池能否复用,最终取决于后端是否接受并维持持久连接:
-
Spring Boot(Tomcat):检查
server.tomcat.connection-timeout ≥ 30s,避免早于 Nginx 超时关闭连接。 -
Node.js(Express):确保未在响应后手动调用
req.socket.destroy()。 -
Go(net/http):确认未调用
SetKeepAlivesEnabled(false)。



















