Nginx轮询本身均匀,但Keep-Alive导致长连接绑定单台后端,引发分流不均;需通过upstream keepalive限制空闲连接数、location中配置HTTP/1.1长连接三要素及合理超时来优化。

理解 Keep-Alive 对轮询调度的影响
在 Nginx 的 upstream 轮询(round-robin)模式下,客户端复用 TCP 连接(即开启 keepalive)会导致请求不再严格按节点顺序分发。因为 Nginx 默认会把同一个长连接上的所有请求都转发给后端的同一个 server,直到该连接关闭或超时。这会让某些后端实例持续接收流量,而其他实例空闲,看起来像“分流不均”。
确认是否是 Keep-Alive 引起的问题
先排除其他常见原因(如后端响应慢、健康检查异常、hash 调度误配等),再聚焦 Keep-Alive:
- 检查客户端是否启用长连接:看请求头是否有
Connection: keep-alive,以及Keep-Alive: timeout=xx - 观察 Nginx access log 中同一 client IP + port 在短时间内反复命中同一个 upstream server
- 用
ss -tnp | grep :<upstream_port></upstream_port>查看后端连接数分布,若某节点连接数远高于其他节点,且连接长时间存在,大概率是 Keep-Alive 复用所致
调整 Nginx 配置缓解分流偏差
核心思路是控制连接复用粒度,避免单个连接长期绑定单一后端:
- 在 upstream 块中设置
keepalive N;(例如keepalive 32;),限制每个 worker 进程与每个后端保持的空闲连接数,防止连接池“囤积”在某个节点 - 在 location 或 server 块中显式关闭客户端长连接:
keepalive_timeout 0;,或设为较短值(如keepalive_timeout 5s;) - 禁用 upstream 连接复用(不推荐生产环境高频场景):
proxy_http_version 1.0;+proxy_set_header Connection '';,强制每次请求建新连接 - 升级到 Nginx 1.21.4+ 可尝试
random two least_conn;等更均衡的负载策略,但需评估兼容性
配合后端与监控做交叉验证
单靠 Nginx 日志可能不够直观,建议联动排查:
- 在后端服务加日志,记录来源 IP + upstream server 名称(可通过
X-Forwarded-For和自定义 header 透传) - 用 Prometheus + nginx-vts-exporter 或 openresty-lua 监控各 upstream 的 active conn、request count、response time,看是否存在连接数/请求数双高现象
- 模拟压测时使用短连接(curl -H "Connection: close")对比结果,若此时分流均匀,基本可锁定 Keep-Alive 是主因


















