Nginx upstream keepalive需协同proxy_http_version 1.1、proxy_set_header Connection ''及keepalive N三者生效,仅设keepalive无效;其控制后端空闲连接池大小,与客户端keepalive_timeout无关。

在 Nginx 作为负载均衡器的场景下,合理配置 keepalive 相关指令能显著提升后端连接复用率,降低 TCP 握手与释放开销,缓解后端服务连接压力。关键不在于“开或不开”,而在于前后端 keepalive 行为的协同匹配。
理解两个不同层级的 keepalive
Nginx 中存在两组独立控制 keepalive 的指令,作用对象不同,必须区分清楚:
-
upstream 模块的
keepalive:定义 Nginx 与后端服务器之间**保活连接池的最大空闲连接数**(如keepalive 32;),仅对 HTTP/1.1 长连接生效,需配合proxy_http_version 1.1和proxy_set_header Connection ''使用; -
http/server/location 块的
keepalive_timeout:控制 Nginx 与客户端之间的连接保持时间(如keepalive_timeout 60s;),影响前端连接复用,但不直接影响 upstream 连接复用率。
正确启用 upstream keepalive 的必要配置
仅写 keepalive N 不足以生效,必须补齐以下三项,否则 Nginx 仍会为每个请求新建后端连接:
- 显式设置 HTTP/1.1 协议:
proxy_http_version 1.1; - 清除客户端传来的 Connection 头(避免继承 close):
proxy_set_header Connection ''; - 启用 keepalive 连接池:
keepalive 32;(数值建议设为单个 worker 进程预期并发后端连接的 1–2 倍,通常 16–64 合理)
示例 upstream 配置:
upstream backend {server 10.0.1.10:8080;
server 10.0.1.11:8080;
keepalive 32;
}
避免常见误配导致 keepalive 失效
以下配置看似合理,实则让 upstream keepalive 形同虚设:
- 遗漏
proxy_set_header Connection '',导致 Nginx 转发客户端的Connection: close,后端主动断连; - 后端服务自身关闭了 keepalive(如 Tomcat 的
connectionTimeout过短、或未启用keepAlive); - 使用了
proxy_buffering off+proxy_cache组合,某些旧版 Nginx 在缓存未命中时会绕过 keepalive 连接池; - 健康检查(health_check)过于频繁且未配置
match或使用非 HTTP/1.1 请求,意外耗尽空闲连接。
验证 keepalive 是否真正生效
不依赖日志猜测,可通过以下方式确认:
- 观察后端服务器的 TIME_WAIT 连接数是否明显下降(如用
ss -s | grep -i time); - 在 Nginx 开启
debug日志级别,搜索"keepalive" "reuse" "create"等关键词,确认连接复用行为; - 用
curl -v http://your-proxy/查看响应头是否含Connection: keep-alive,并多次请求观察 TCP 连接复用(配合tcpdump或ss -tni); - 监控 Nginx 内置变量
$upstream_conn(当前复用的后端连接 ID)和$upstream_addr,相同连接 ID 多次出现即表示复用成功。











