least_conn是静态调度算法,仅基于Nginx维护的活跃连接数选择后端,不感知容量变化;动态伸缩需依赖外部机制如监控系统、配置热重载、OpenResty/Lua或NGINX Plus商业API。

least_conn 本身不感知后端容量变化,也不能自动伸缩上限;所谓“自动伸缩”必须靠外部机制驱动配置变更或运行时干预。Nginx 原生不支持动态更新 max_conns 或实时读取后端指标(如 CPU、内存、队列长度),因此需结合监控系统、配置热重载或 OpenResty/Lua 扩展来实现近似效果。
明确 least_conn 的静态本质
least_conn 是一个实时但静态的调度算法:它只根据 Nginx 当前维护的每个 upstream server 的活跃连接数(即已建立、未关闭的 proxy 连接)做选择,不拉取、不计算、也不响应后端上报的任何性能指标。它的“最小连接”只是计数器比大小,不是智能扩缩容。
- max_conns 是硬编码值,写死在配置里,重启或重载才生效,无法随 CPU 使用率升高自动从 800 调到 1200
- 即使你用 Ansible 或 CI/CD 每分钟生成新配置,那也只是“伪自动”,不是 Nginx 内置能力
- Nginx 社区版无运行时 API 修改 upstream 参数;NGINX Plus 提供 REST API,但需商业授权
用健康检查 + max_conns 实现“被动弹性”
虽然不能主动伸缩,但可通过健康状态变化间接释放/收紧容量边界:
- 为每个 server 配置
max_fails=3 fail_timeout=30s,当后端连续失败,Nginx 将其标记为不可用,等效于“临时下线”,流量自动绕过 - 搭配
max_conns=600,一旦该节点连接数达 600,新请求立即跳转——这相当于设定了可承受的硬上限,避免雪崩 - 若后端部署了自愈逻辑(如 Kubernetes HPA 触发扩容),新 Pod 上线后注册进服务发现,再通过动态 upstream(如 Consul + nginx-upstream-check-module)加入集群,Nginx 自动将其纳入 least_conn 调度池
借助 OpenResty + Lua 实现轻量级动态限流
若需真正运行时调整单节点并发上限,OpenResty 是最可行路径:
- 用 Lua 读取 Prometheus 指标(如
node_cpu_seconds_total{mode="idle"}),计算当前空闲度 - 按公式映射为动态
max_conns值,例如:空闲率 ≥ 70% → max_conns = 1000;50%~70% → 800;<50% → 400 - 通过共享字典(shared dict)缓存各 backend 的实时阈值,在
balancer_by_lua_block中调用balancer.set_current_peer()并配合连接数判断,绕过原生 least_conn,实现“带容量感知的最小连接”逻辑 - 注意:此方式需关闭原生
least_conn,改用自定义负载均衡器,且对 Lua 编程和 Nginx 生命周期有要求
推荐生产级折中方案:分层+灰度+可观测
不追求全自动,而用结构化设计降低运维成本:
-
按规格分组 upstream:将 8C16G 节点归入
upstream high_perf { least_conn; server ... max_conns=1800; },4C8G 归入medium_perf { ... max_conns=800; } - 滚动更新时加 slow_start=60s:新实例上线后权重线性上升,避免瞬间打满,给监控和熔断留出反应时间
-
暴露 stub_status + 自定义日志字段:记录每个请求实际转发到的 server 及其当时连接数,用 Grafana 看板追踪
upstream_addr与upstream_connect_time分布,及时发现失衡 - 配合后端主动上报(如 /health?include=load),Nginx 用
health_check模块做 HTTP 探针,把高负载节点临时踢出,等效“手动缩容”


















