必须同时配置proxy_http_version 1.1、proxy_set_header Connection ""和upstream keepalive N三项,缺一不可;否则Nginx无法复用后端连接,TCP握手与TLS协商开销无法降低。

要让 Nginx 的 upstream keepalive 真正起作用、降低回源时的 TCP 握手和 TLS 开销,不能只写一行 keepalive 32;。它是一套协同机制,协议、头部、连接池参数三者必须同时到位,缺一不可。
必须配齐的三项基础配置
单独配置任意一项都无效:
-
启用 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 32–128:按单个 worker 平均并发后端连接数的 1–2 倍设定;设太小易耗尽,太大易积压 TIME_WAIT。
- keepalive_requests 500:单个连接最多处理请求数,默认 100;高频小请求可调高,避免低频连接长期占用但无实际收益。
- keepalive_timeout 15–30s:空闲连接存活时间,默认 60s;适当缩短可加快回收,减少僵死连接;建议略小于后端服务的 keepalive 超时(如后端设 60s,Nginx 设 55s)。
防静默断连:启用 socket 层保活
在 CDN 回源或跨公网场景下,中间设备(如防火墙、WAF、LB)可能悄无声息地切断空闲连接,而 Nginx 无法感知。此时需底层探测:
- 添加
proxy_socket_keepalive on 60s 5s 3;:空闲 60 秒后开始探测,每 5 秒发一次心跳,连续 3 次无响应则关闭 socket。 - 该指令作用于 upstream 连接池中的每个 socket,与 HTTP 的
Connection: keep-alive无关,专治“连接还在但实际已断”的问题。
确认后端服务兼容长连接
上游连接池能否复用,最终取决于后端是否接受并维持持久连接:
-
Spring Boot(Tomcat):检查
server.tomcat.connection-timeout ≥ 30s,避免早于 Nginx 超时关闭连接。 -
Node.js(Express):确保未在响应后手动调用
req.socket.destroy()。 -
Go(net/http):确认未调用
http.Server.Close()或显式关闭连接;默认支持 HTTP/1.1 长连接。 - 验证方式:查看后端响应头是否含
Connection: keep-alive;用curl -I多次请求,观察connection_requests日志变量是否递增。











