单纯调大或调小weight无法应对突发流量下的单机过载,真正有效的是“权重锚定+连接控制+健康反馈”三层协同:weight锚定长期能力基线,least_conn防连接堆积,健康检查自动剔除失能节点,并需外部闭环调控实现真动态响应。

单纯调大或调小 weight 无法应对突发流量下的单机过载——它只是静态分配倾向,不感知实时负载。真正起效的是“权重锚定 + 连接控制 + 健康反馈”三层协同。
用 weight 锚定长期能力基线,不用于实时开关
weight 应反映服务器的相对处理能力,比如新机器设 weight=5、旧机器设 weight=2,形成理论承接比 5:2。这能避免突发来临时,低配机因和高配机平分流量而率先打满。但注意:
- weight 不是限流阀,设成
weight=1不代表只收 10% 流量,尤其在请求数少时仍可能连续打到该节点 - 避免极端比例(如 10:1),否则高权重点持续承压,失去容错余量
- 所有节点
weight ≥ 1,防止瞬时抖动导致某节点被完全跳过
必须搭配 least_conn 防止连接堆积
突发短连接洪峰下,仅靠 weight 会失效:某台高权重点正处理 5 个慢请求,连接数已接近上限,但轮询仍继续派发。启用 least_conn 后,Nginx 先按权重划分“应得份额”,再在同权重组里选活跃连接最少的节点,实现毫秒级绕行。
- 配置示例:
upstream backend { least_conn; server 10.0.1.10:8080 weight=5; server 10.0.1.11:8080 weight=2; } - 配合
max_conns 10;限制单机最大并发,超出请求排队或返回 503 - 再加
queue 30 timeout=5s;缓冲瞬时洪峰,防冷启动或慢 SQL 导致的短暂不可用
靠健康检查自动剔除失能节点
weight 再合理,也救不了已卡死的节点。必须开启主动健康检查,让 Nginx 实时感知状态:
- 配置
health_check interval=3 fails=2 passes=2;,探测/health?ready=1 - 连续失败 2 次后,该节点自动标记为
down,weight 失效,剩余节点按新权重重新归一化承接流量 - 避免只依赖
max_fails被动机制——它需真实请求触发失败,而主动检查可在请求到达前就隔离异常节点
真动态响应需外部闭环调控
Nginx 原生不支持运行时改 weight。要实现“CPU 突增 → 自动降权”,得引入外部信号:
-
OpenResty + Lua:用
lua_shared_dict缓存各节点 CPU 和响应时间,每 3 秒探测一次,在balancer_by_lua_block中实时计算并选节点 - Consul + nginx-upsync-module:把节点 P95 延迟写入 Consul KV,Nginx 每 300ms 拉取更新,故障节点自动权重置 0
-
HTTP API 方案:通过
POST /upstream/servers接口由 Prometheus 告警脚本驱动调权,比如延迟超 500ms 就把 weight 从 5 降到 2











