least_conn算法通过将新请求优先分发给当前活跃连接数最少的健康后端节点,有效缓解长耗时请求导致的负载不均;它不依赖轮询顺序或ip绑定,而是实时依据tcp连接数(含keepalive空闲连接)调度,需配合健康检查、max_conns限流和合理keepalive配置才能生效。

least_conn 算法能有效缓解长耗时请求(如文件上传、报表导出、AI推理)带来的后端负载不均问题,核心是把新请求交给当前活跃连接数最少的健康节点,而不是按顺序或按IP硬分配。
为什么轮询在长耗时场景下容易失效
轮询只管“下一个该轮到谁”,不管那台机器是否正卡在一个 30 秒的上传任务里。结果就是:某台后端连接数持续堆积,响应延迟升高、超时增多;而其他节点空闲——监控上常表现为 conn_established 偏高但 CPU/内存利用率却偏低。
- 长连接生命周期长,连接数真实反映“手头活儿”数量
- IP hash 完全绑定客户端,无法动态释放压力
- least_conn 不依赖历史响应时间或资源指标,只看此刻“还连着几个没断的”
基础配置必须写对
least_conn 必须放在 upstream 块第一行,且不能和 ip_hash、hash、weight 混用(开源版会静默忽略 weight):
- 确保 Nginx ≥ 1.3.1(该算法自该版本起正式支持)
- 示例写法:upstream backend { least_conn; server 192.168.1.10:8080; server 192.168.1.11:8080; }
- 若后端性能不均(如一台是 32C 服务器,另两台是 8C),可用 max_conns 实现软性容量控制:高性能节点设 max_conns=2000,普通节点设 max_conns=800
关键配套设置不能少
单独写 least_conn 几乎没用,必须同步调整连接生命周期与健康感知能力:
- 启用主动健康检查:least_conn 不识别假死节点。建议用 nginx_upstream_check_module 或 OpenResty 的 check 指令,例如 check interval=3 rise=2 fall=3 timeout=1 type=http;
- 合理配置 keepalive:upstream 中加 keepalive 32; 复用连接、降低建连开销;但注意 keepalive 空闲连接也会计入活跃数,值不宜过大(如超过 100 可能干扰判断)
- 匹配业务超时:proxy_read_timeout 至少设为最长预期处理时间(如大文件上传设为 7200),避免因超时中断导致连接反复重建、统计失真
怎么验证它真的在起作用
别只看日志请求数,要观察实时连接分布:
- 开启 stub_status 模块,访问 /nginx_status 查看各 upstream server 的 active 连接数是否随时间趋于均衡
- 压测时用 curl -I 多次发起请求,比对各后端 access log 中实际接收的新连接数变化趋势
- 监控 active connections + response time 散点图,警惕“连接数低但延迟高”的异常节点(可能是磁盘满、IO 队列积压)











