nginx默认对每个请求新建后端tcp连接,开启upstream keepalive连接池可复用空闲连接、降低建连开销;需三者齐备:upstream中配置keepalive 32、location中设proxy_http_version 1.1和proxy_set_header connection '',且后端必须支持http/1.1持久连接。

Nginx 默认对每个请求都新建后端 TCP 连接,这在高并发、短响应的 API 场景下会带来明显开销:频繁三次握手、TLS 协商、内核 socket 分配/释放,以及大量 TIME_WAIT 连接堆积。开启 upstream keepalive 连接池,本质是让 Nginx 缓存并复用已建立的空闲连接,跳过重复建连流程,从而大幅降低后端建连开销。
必须显式配置 upstream keepalive,否则不生效
Nginx 不会自动复用后端连接,哪怕后端支持 HTTP/1.1。只加 keepalive 32; 不够,需三者齐备:
- 在
upstream块中声明连接池大小:keepalive 32;(每个 worker 最多缓存 32 个空闲连接) - 在对应
location中启用 HTTP/1.1:proxy_http_version 1.1; - 清除可能干扰的连接头:
proxy_set_header Connection '';
缺一不可。否则 Nginx 仍会发 Connection: close 或降级到 HTTP/1.0,连接无法复用。
合理设置三个协同参数,避免“假复用”或“空转”
单纯开启 keepalive 不代表真正复用成功,需匹配业务节奏与后端能力:
-
keepalive 32–128:按后端单实例稳定并发数 × 0.6~0.8 设定。例如 TomcatmaxConnections=200,可设keepalive 120;若后端只有 2 实例且 QPS 中等,32~64 更稳妥。 -
keepalive_requests 500–1000:单个连接最多转发多少次请求后主动关闭。默认 100 容易导致刚用几次就断,调高可减少重建频次;但不宜盲目设为 10000,以防连接老化或后端静默断连引发upstream prematurely closed connection。 -
keepalive_timeout 15–30s:空闲连接在 Nginx 池中保留时长。必须严格小于后端的 keepalive 超时(如 Spring Boot 默认 60s,则 Nginx 设 20–55s),否则 Nginx 还没关,后端先断,连接池形同虚设。
后端服务必须真正支持并维持长连接
上游连接池能否复用,最终取决于后端是否接受并保持持久连接:
- Spring Boot(Tomcat):确认
server.tomcat.connection-timeout >= 30s,且未设maxKeepAliveRequests=1等限制 - Node.js(Express):检查是否误调
req.socket.destroy()或res.end()后立即关闭 socket - Go(net/http):默认开启,但若代码中调用了
srv.SetKeepAlivesEnabled(false)则需关闭
验证方式:用 curl -I http://backend/ 多次请求,响应头应含 Connection: keep-alive,且无 Connection: close;抓包观察多个请求是否复用同一 TCP 连接。
配套优化提升复用率和稳定性
仅调参还不够,还需防止中间链路“悄无声息断连”:
- 启用 socket 层保活(尤其跨公网/经 WAF 场景):
proxy_socket_keepalive on 60s 5s 3;,空闲 60 秒后每 5 秒发心跳,3 次失败即关闭 - 避免客户端透传
Connection: close:禁用keepalive_disable msie6等过时指令 - 监控复用效果:看
nginx_stub_status中Active connections与Writing比例;用ss -tn state established | grep :8080 | wc -l对比连接数是否显著下降;$connection_requests日志字段平均值 ≥ 5 是复用有效的信号
不复杂但容易忽略。











