核心是客户端、Nginx、后端三者协同复用TCP连接以跳过三次握手和TLS协商:需协议(HTTP/1.1)、头部(清空Connection)、连接池(upstream keepalive)、超时(keepalive_timeout/keepalive_requests)四者齐备,并确保后端及中间设备兼容长连接。

核心是让客户端、Nginx、后端三者之间真正复用 TCP 连接,跳过重复的三次握手和 TLS 协商。这不是单设一个参数就能生效的事,而是协议、头部、连接池、超时四者协同的结果。
客户端到 Nginx 的 keepalive 复用
这是减少前端请求延迟的第一环。关键看 keepalive_timeout 是否贴合真实访问节奏:
- 静态资源或 CDN 边缘节点:设为 10–30 秒。页面加载快、请求分散,太长反而积压连接
- 移动端 API:5–15 秒更稳妥。App 切后台后常在 60 秒内主动断连,Nginx 设再高也白等
- 常规 Web 站点(含 HTML/CSS/JS 并行加载):30–65 秒较合理。主流浏览器空闲超时虽达 5 分钟,但首屏关键请求集中在前 20 秒内
- HTTPS 场景必须配 TLS 会话复用:ssl_session_cache shared:SSL:10m; ssl_session_timeout 4h; 否则 TCP 虽复用,TLS 握手仍可能重做
Nginx 到后端的 upstream keepalive 池
这才是降低后端建连压力的核心。只写 keepalive 32; 是无效的,必须三件套齐备:
-
启用 HTTP/1.1:在 proxy location 中加
proxy_http_version 1.1;(HTTP/1.0 默认关闭长连接) -
清空 Connection 头:加
proxy_set_header Connection "";,否则 Nginx 可能继承客户端的Connection: close -
声明连接池大小:在 upstream 块中设
keepalive 32;,表示每个 worker 进程最多缓存 32 个空闲连接
配套建议值:keepalive_requests 500(避免低频连接长期占用)、keepalive_timeout 15–30s(比默认 60s 更快回收僵死连接)。
后端服务必须兼容长连接
上游连接池能否复用,最终取决于后端是否接受并维持持久连接:
- Spring Boot(Tomcat):确认
server.tomcat.connection-timeout ≥ 30s,且maxKeepAliveRequests不为 -1 或过小 - Node.js(Express):检查是否在响应后误调
req.socket.destroy() - Go(net/http):默认开启 keep-alive,但若显式调用
SetKeepAlive(false)就会失效
若后端提前关闭连接,Nginx 的 keepalive 池就变成“空转”,所有优化归零。
防中间链路静默断连
公网、云 WAF 或 NAT 设备可能悄无声息地切断空闲连接,导致 Nginx 复用失败后报 upstream prematurely closed connection:
- 启用 socket 层保活:
proxy_socket_keepalive on 60s 5s 3; - 含义:连接空闲 60 秒后开始探测,每 5 秒发一次 TCP 心跳,连续 3 次无响应则主动关闭
- 该机制与 HTTP 的
Connection: keep-alive无关,专治“连接看似存在实则已断”的问题











