排查加权轮询下长连接复用冲突,关键是确认连接是否真被复用及是否干扰轮询:需验证upstream keepalive是否启用、proxy头与协议是否匹配、连接数与权重是否脱节,并协同后端对齐连接生命周期。

排查加权轮询下的长连接复用冲突,关键不是看权重配得对不对,而是确认“连接是否真被复用了”,以及“复用行为有没有和轮询逻辑打架”。常见表现是:明明配置了 weight,但某台后端连接数远高于其他节点,且大量请求卡在 ESTABLISHED 状态不释放,stub_status 显示活跃连接堆积,而访问日志里却看不到对应请求量——说明连接被复用,但没被轮询调度到该复用链路上。
检查 upstream keepalive 是否真正生效
加权轮询本身不管理连接生命周期,keepalive 指令才是复用的开关。若没启用或配置错,Nginx 会为每个请求新建后端连接,掩盖轮询效果,也导致复用冲突:
- 确认
upstream块中显式写了keepalive N(如keepalive 32),不能只靠proxy_http_version 1.1; - 检查是否所有
server行都使用 HTTP 协议直连(如192.168.1.10:8080),HTTPS 后端会绕过连接池; - 用
nginx -T | grep -A5 "upstream.*{"验证最终生效配置,避免被 include 文件覆盖或遗漏。
验证 proxy 头与协议是否破坏复用链路
即使启用了 keepalive,只要有一处头信息或协议不匹配,Nginx 就会主动断开复用连接,退回到短连接模式,造成“看似复用、实则新建”的假象:
- location 中必须有
proxy_http_version 1.1; - 必须设置
proxy_set_header Connection "",清除可能来自后端的Connection: close响应头; - 避免手动添加
proxy_set_header Connection "keep-alive",这是冗余且易干扰的; - 禁用
ip_hash或其他会话保持指令——它们和长连接复用结合时,会让连接长期绑定单一后端,彻底架空轮询逻辑。
比对连接数与请求分发是否脱节
加权轮询按请求计数分配,而长连接复用会让多个请求走同一条 TCP 连接。若后端响应快、连接复用率高,轮询序列就容易“跳步”,造成表观倾斜:
- 用
ss -s或netstat -an | grep :8080 | wc -l统计各后端当前 ESTABLISHED 连接数,对比其与配置权重的比例差异; - 若某节点连接数占比远超其权重(如 weight=2 却占总连接 70%),再查它的
accept queue是否溢出(netstat -s | grep "listen overflows"); - 临时关闭
keepalive,用ab -n 1000 -c 100 -k测试短连接场景,观察$upstream_addr分布是否回归权重比例——若回归,说明冲突确实来自复用机制。
协同后端服务确认生命周期对齐
复用冲突常源于 Nginx 和后端对“连接该不该关”判断不一致。比如后端提前关闭空闲连接,Nginx 却还往里发请求,触发重试或 502;或者后端迟迟不关,Nginx 又等不到响应,导致连接挂死:
- 后端的
keepAliveTimeout(如 Tomcat 的connectionTimeout)必须大于 Nginx 的proxy_read_timeout; - 若后端支持健康检查,应在
upstream中统一开启,避免因某节点短暂无响应被剔除,其余节点被迫承接更多复用连接; - Kubernetes 环境下,确保
preStop hook配合terminationGracePeriodSeconds,给 Nginx 留出时间自然释放连接,而非强制 kill。











