least_conn算法通过实时选择活跃连接数最少的后端节点分配新请求,特别适合WebSocket、SSE、HTTP/2流和文件上传等长连接场景,需配合健康检查、max_conns和keepalive配置才能生效。

least_conn 算法能有效优化长连接 TCP 集群的流量分布,核心在于它不看历史、不猜性能,只盯住每个后端当前“还连着几个没断的连接”——这个数字越小,新请求就越优先发给它。对 WebSocket、SSE、HTTP/2 流、文件上传等长生命周期连接场景,这比轮询或 IP hash 更贴近真实负载。
为什么 least_conn 特别适合长连接集群
长连接的特点是:建连开销大、单连接持续时间长、连接数直接反映服务“手头活儿”的多少。而 least_conn 正是基于这个指标做决策:
- 一个刚处理完报表导出的节点,连接迅速释放,立刻变为空闲候选
- 另一个正维持 50 个 WebSocket 的节点,哪怕 CPU 很低,也会被跳过
- 连接数为 0 的节点天然获得最高优先级;达到 max_conns 则自动剔除,不靠人工干预
- 它不依赖响应时间或资源使用率,避免了监控延迟或指标失真带来的误判
关键配置要点(非可选)
仅写 least_conn; 不够,必须配套以下三项才能真正起效:
-
健康检查必须开启:least_conn 不识别进程卡死、服务假活。需配合
nginx_upstream_check_module或 Nginx Plus 主动探活(如每 5s GET /health),失败节点及时摘除 -
max_conns 要设合理上限:例如高性能节点设
max_conns=2000,普通节点设800,实现“能力越强,容得越多”,而非盲目压榨 -
keepalive 设置需权衡:upstream 中启用
keepalive 32可复用连接、降开销,但空闲连接仍计入活跃数。若发现调度迟钝,可调低至 16 或配合proxy_http_version 1.1+Connection: close控制生命周期
避开常见误用陷阱
很多集群上线后效果不佳,问题往往出在这些细节上:
- 混用 weight 是无效的:开源 Nginx 的 least_conn 完全忽略 weight 参数。所谓“加权 least_conn”,只能靠 max_conns 实现软性倾向
- 客户端不复用连接会失效:如果前端每请求都新建 TCP 连接(未设 keep-alive),活跃连接数瞬时涨落剧烈,least_conn 统计失去意义。需同步调整客户端连接池与超时设置
-
不观察真实连接数等于盲调:上线后务必通过
ss -s或netstat -an | grep :端口 | grep ESTAB | wc -l对比各后端 ESTABLISHED 数,再结合 Nginx stub_status 的 Active connections 分布交叉验证
适合启用 least_conn 的信号(不是凭感觉)
当出现以下任一现象,说明轮询已失衡,least_conn 值得立即尝试:
- 监控显示某台后端 conn_established 持续高于其他节点 2 倍以上,但 CPU/内存却明显偏低
- 接口 P99 响应时间远高于 P50(比如 120ms vs 3.2s),说明请求耗时不均、存在长尾堆积
- 日志中频繁出现 upstream timed out 或连接拒绝(connection refused / too many open files)
- 已有 WebSocket 连接数多、HTTP/2 流并发高,或大量文件上传任务并行运行











