关键是要完整配置upstream连接复用机制:在upstream块中设keepalive(32–200)、keepalive_requests(500–1000)和keepalive_timeout(15–30s),并在location中配proxy_http_version 1.1与proxy_set_header connection '',同时确保后端支持http/1.1长连接。

要显著降低负载均衡器的 TCP 握手开销,关键不是加一行 keepalive,而是完整配置 upstream 连接复用机制,让 Nginx 真正复用后端连接,避免每个请求都新建 TCP 连接。
在 upstream 块中正确启用连接池
keepalive 必须放在 upstream 块内,且需与两个参数协同生效:
- keepalive N:每个 worker 进程为该 upstream 保留的空闲长连接最大数,不是总连接数。建议设为 32–64(小规模集群)或 64–200(高并发、多后端实例场景);值过大会占用后端资源,过小则复用率低。
- keepalive_requests M:单个 keepalive 连接最多转发多少个请求后主动关闭,默认 100。API 类短请求可调高至 500–1000,防止连接长期空闲却未释放。
- keepalive_timeout T:空闲连接保持存活时间(秒),默认 60s。建议设为 15–30s,平衡复用率与及时回收,避免后端堆积大量 idle 连接。
示例:
upstream api_backend {
server 10.0.2.10:8080;
server 10.0.2.11:8080;
keepalive 64;
keepalive_requests 500;
keepalive_timeout 20s;
}
在 location 中强制启用 HTTP/1.1 并清理连接头
即使 upstream 配了 keepalive,若 proxy_pass 发送 Connection: close,后端仍会断连。必须显式配置:
- proxy_http_version 1.1:确保使用支持持久连接的协议版本;
-
proxy_set_header Connection '':清空 Connection 头,阻止 Nginx 自动注入
close; - 无需手动加
Keep-Alive头,Nginx 会根据 upstream 设置自动处理。
对应转发配置示例:
location /v1/ {
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
确认后端服务支持并维持 HTTP/1.1 持久连接
上游连接池能否真正复用,取决于后端是否接受并保持长连接:
-
Spring Boot(Tomcat):默认支持,但需检查
server.tomcat.connection-timeout≥ 30s,否则连接被提前关闭; -
Node.js(Express + http.Server):避免在响应后调用
req.socket.destroy()或误设res.connection.destroy(); -
Go(net/http):默认开启 keepalive,若代码中调用了
srv.SetKeepAlivesEnabled(false),需关闭该设置。
验证方式:抓包看后端响应是否含 Connection: keep-alive,或观察后端日志中连接复用行为(如 Tomcat 的 Keep-Alive 日志标记)。
避免常见误区
几个容易导致 keepalive 失效的操作:
- 把
keepalive写在http或server块里——它只在upstream块内有效; - 遗漏
proxy_set_header Connection '',尤其在有旧版兼容配置时; - 后端设置了过短的 idle timeout(如 5s),导致连接刚建好就被关掉;
- 混用 HTTP/1.0 和 HTTP/1.1 请求,破坏连接复用上下文。
配置完成后,可观测后端 TIME_WAIT 数量下降、平均延迟(尤其是 P95)收窄、CPU 花费在 SSL/TCP 握手上的比例明显降低。











