nginx upstream keepalive配置核心是每个worker进程缓存指定数量空闲长连接以复用,需配合keepalive_requests和keepalive_timeout协同调优,并确保proxy_http_version 1.1及proxy_set_header connection ''生效,缺一不可。

配置 upstream 中的 keepalive 连接池,核心是让 Nginx 复用到后端的空闲 TCP 连接,而不是每次请求都新建连接。所谓“keepalive_conns”并非 Nginx 官方参数名——正确指令是 keepalive N,它定义的是每个 worker 进程为该 upstream 保持的最大空闲长连接数,不是总连接上限,也不是并发连接能力本身。
keepalive 参数的本质与常见误区
很多人误以为 keepalive 64 表示“最多连 64 条”,其实它表示:单个 Nginx worker 进程,在该 upstream(比如 backend)下,最多缓存 64 个已建立、当前空闲、可立即复用的连接。活跃请求仍会新建连接,超出部分不会被拒绝,但空闲连接池不会超过这个数。
- 错误写法:
server 10.0.1.10:8080 keepalive 64;—— keepalive 必须独立成行,且只能出现在upstream { ... }块内 - 错误理解:设成 1024 就能扛住万级并发 —— 实际受后端处理能力、系统文件描述符、TIME_WAIT 回收速度共同制约
- 典型风险:值过大 + 后端连接数限制紧(如 Tomcat maxConnections=200),会导致连接被后端主动 RST,反而触发重试和超时
根据后端能力反推合理 keepalive 值
不能拍脑袋定数字,要结合后端单实例的稳定承载能力来算。公式逻辑是:
keepalive ≈ (后端单实例最大健康连接数 × 安全系数) ÷ Nginx worker 进程数
- 安全系数建议取 0.6~0.8,留出缓冲空间应对突发流量或慢响应
- 例如:后端是 Spring Boot + Tomcat,默认
maxConnections=200,Nginx 有 4 个 worker,则keepalive ≈ 200 × 0.7 ÷ 4 = 35→ 可设为32或48 - 若后端是 Go Gin 或 Node.js(轻量连接模型),且部署了 8 个 worker,单实例可稳撑 1000 并发,则
keepalive ≈ 1000 × 0.75 ÷ 8 ≈ 94→ 设96更稳妥
配套参数必须协同调优
只配 keepalive 不生效。它必须和以下两个参数联动,构成完整复用链路:
-
keepalive_requests M:单个 keepalive 连接最多转发多少次请求后主动关闭。默认 100 太保守,高吞吐场景建议
500~2000。设太小(如 100)会导致连接频繁进出池子;设太大(如 10000)可能因后端空闲超时早于 Nginx 而断连 -
keepalive_timeout T:空闲连接在池中保留多久(秒)。关键原则是 必须小于后端服务的 keepalive timeout(如 Nginx 设
25s,后端 Tomcat 的connectionTimeout至少得是30s或更高),否则连接会被后端先关掉,Nginx 复用时发现连接已失效,报upstream prematurely closed connection
验证是否真正生效的实操方法
别只看配置有没有写对,要观察真实连接行为:
- 执行
ss -tnp | grep :8080 | grep ESTAB | wc -l(假设后端端口是 8080),持续压测时该数值应稳定在keepalive × worker 数附近,而非随 QPS 线性上涨 - 用
tcpdump -i any port 8080 -w backend.pcap抓包,过滤出 SYN 包数量 —— 优化后单位时间内 SYN 次数应明显下降 - 检查后端 access log 或响应头:正常复用时,多数响应应含
Connection: keep-alive;若大量出现Connection: close,说明后端在干预,需排查错误响应、WAF 插件或调试开关











