least_conn算法仅统计后端活跃tcp连接数并选择最少者,不感知cpu、响应时间等指标;其有效性依赖keepalive复用、后端连接池及健康检查配合,适合长连接与耗时差异大的场景。

Nginx 的最少连接算法(least_conn)本身不识别“繁忙”,它只统计并比较各后端当前与 Nginx 保持的活跃 TCP 连接数,然后把新请求交给数字最小的那个。所谓“繁忙”,是运维人员对高连接数的主观解读;而 Nginx 只做客观计数——连接少 ≠ 负载低,但通常意味着该节点正在处理的并发请求更少。
least_conn 如何间接反映后端压力
它依赖一个隐含前提:后端处理能力相对均衡、连接生命周期能反映真实负载。
- 每个活跃连接通常对应一个未完成的请求(如长连接下的 WebSocket、文件上传、gRPC 流)
- 若某后端因 CPU 卡死、GC 暂停或慢 SQL 导致响应延迟,请求堆积 → 连接数持续升高 →
least_conn自动绕开它 - 反之,刚完成请求、连接已释放的节点连接数归零,成为首选
但这个机制有边界:
- 它不看 CPU 使用率、内存占用、响应时间或错误率
- 如果后端进程僵死但 TCP 连接未断(如 hang 住但 keepalive 未超时),连接数仍被计入,“假空闲”会导致误判
- 短连接场景下(每个请求建一次连、立刻关),连接数瞬间归零,
least_conn几乎退化为轮询
让连接数真正代表“繁忙程度”的关键配置
要让 least_conn 发挥作用,必须确保连接数统计有意义:
-
启用 keepalive 连接复用
- upstream 中配置
keepalive 32;(推荐 16–64) - 后端服务也要支持连接池(如 Tomcat 设置
maxKeepAliveRequests > 0,Go HTTP Server 默认复用) - 避免每请求新建连接,否则连接数无法累积反映真实并发压力
- upstream 中配置
-
配 max_fails + fail_timeout 主动剔除异常节点
- 例如:
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s; - 当 Nginx 发现连续失败(连接拒绝、超时、5xx),就临时移出调度池,防止连接数虚高却持续被选中
- 例如:
-
叠加 passive 健康检查(proxy_next_upstream)
- 在 location 中配置:
proxy_next_upstream error timeout http_500 http_502 http_503; proxy_next_upstream_tries 3;
- 一旦后端返回 502/503 或响应超时,Nginx 会尝试下一个节点,并触发
max_fails计数
- 在 location 中配置:
-
(进阶)启用主动健康检查(需 Nginx Plus 或第三方模块)
- 定期发
/health请求,根据 HTTP 状态码和响应内容判断是否存活 - 比被动检查更早发现“连接数正常但业务已卡死”的情况
- 定期发
实际效果取决于后端行为模式
- ✅ 适合:请求耗时差异大(如 AI 推理 100ms~5s)、长连接多(WebSocket、SSE)、后端无明显性能碎片
- ⚠️ 效果弱:所有请求都很快(
本质上,least_conn 是一个基于连接状态的轻量级负载信号。它不智能,但足够直接——只要连接数能真实反映处理队列长度,它就能把流量导向“此刻最空”的节点。











