要让upstream的keepalive真正发挥长连接池作用,需根据后端承载能力、Nginx工作进程数和流量特征精准配置:keepalive值指每个worker对每台server的最大空闲连接数,须≤后端单实例并发上限;需匹配后端空闲超时(如Tomcat connection-timeout≥45s),并配置keepalive_timeout(建议比后端小5秒)和keepalive_requests(如500);同时location中必须启用proxy_http_version 1.1并清空Connection头。

要让 upstream 的 keepalive 真正发挥长连接池作用,关键不是盲目调大数值,而是根据后端承载能力、Nginx 工作进程结构和实际流量特征做精准匹配。值设小了复用率低,设大了可能压垮后端或耗尽系统资源。
先算清每个 worker 能管多少条空闲连接
keepalive 后面的数字(比如 keepalive 64)指「每个 worker 进程」对「该 upstream 中每台 server」最多缓存的空闲长连接数。它不是全局总数。
- 若你有
worker_processes 4,upstream 里定义了 2 台后端(server a:8080; server b:8080;),那么理论最大空闲连接数是4 × 2 × 64 = 512 - 这个数字必须 ≤ 后端单实例能稳定处理的并发连接上限(如 Tomcat 的
maxConnections、Go 的http.Server.MaxIdleConnsPerHost) - 建议初始值按后端单实例承载力的 60%~80% 设置。例如后端 maxConnections=200,可先试
keepalive 128
再看后端是否真能接住这些连接
Nginx 保持的连接,后端得愿意一直挂着。如果后端自己早早断开,Nginx 的 keepalive 就成摆设。
- Spring Boot(Tomcat):检查
server.tomcat.connection-timeout,建议 ≥ 45s,且大于 Nginx 的keepalive_timeout - Go:确认未调用
SetKeepAlivesEnabled(false);推荐设置MaxIdleConnsPerHost≥ Nginx 的 keepalive 值 - Node.js:避免在响应后立即
req.socket.destroy();默认支持,但需关掉手动关闭逻辑 - 验证方法:抓包看后端响应头是否有
Connection: keep-alive,且无Connection: close
配合 timeout 和 requests 控制连接“寿命”
只设 keepalive 数值,不控生命周期,容易出现连接“僵而不死”或“用几次就扔”,影响稳定性。
-
keepalive_timeout 20s:空闲连接在池中最多躺 20 秒,超时即关。必须比后端空闲超时短至少 5 秒 -
keepalive_requests 500:单个连接最多转发 500 次请求后强制回收。高并发下可设到 1000,防状态累积(尤其 Java 应用) - 这两个参数从 Nginx 1.15.3+ 才完全支持,老版本(如 1.12)只认 keepalive,不自动限制请求数和超时
别漏掉 proxy 层的三件套
upstream 的 keepalive 是“池子”,但请求进不来、协议不对、头被污染,池子再深也没人用。
-
proxy_http_version 1.1:必须显式开启,HTTP/1.0 不支持持久连接语义 -
proxy_set_header Connection "":清空客户端传来的 Connection 头(比如close),否则 Nginx 可能原样转发,导致后端直接断连 - 这两项必须写在
location块里,和proxy_pass在同一作用域



















