要真正降低nginx到后端的tcp握手开销,关键在于协议层、头部控制和连接池参数三者严格配合:必须同时配置proxy_http_version 1.1;、proxy_set_header connection "";和upstream中keepalive n;,缺一不可,并建议补充keepalive_requests、keepalive_timeout及proxy_socket_keepalive防静默断连。

要真正降低 Nginx 到后端的 TCP 握手开销,关键不是“加 keepalive”,而是让 upstream 连接池能稳定复用已建立的连接。这需要协议层、头部控制和连接池参数三者严格配合,缺一不可。
必须配齐三项基础配置
只在 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 数值不够,建议搭配 keepalive_requests 和 keepalive_timeout 使用:
- keepalive 32–128:按单个 worker 平均并发后端连接数的 1–2 倍设定;设太小易耗尽,太大易积压 TIME_WAIT。
- keepalive_requests 500:单个连接最多处理请求数,默认 100,高频小请求可调高,避免低频连接长期占用。
- keepalive_timeout 15–30s:空闲连接存活时间,默认 60s;适当缩短可加快回收,减少僵死连接。
补充 socket 层保活防静默断连
在 CDN 回源或跨公网场景下,中间设备可能悄无声息地切断空闲连接。需额外启用底层探测:
- 添加 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)。 - 验证方式:抓包观察后端响应头是否含
Connection: keep-alive,或监控后端的 ESTABLISHED 连接数是否趋于稳定。











