nginx 不支持根据健康信息自动调整权重,weight 是静态配置项,需依赖外部机制实现动态调权;必须配置健康检查(被动或主动),并结合 consul、openresty 或 http api 等方案构建采集-决策-执行闭环,同时依托可观测性持续验证效果。

Nginx 本身不支持根据健康信息自动调整权重——weight 是静态配置项,加载后即固化,不会随 CPU、响应延迟或错误率变化而改变。所谓“自动调权”,必须依赖外部协同机制,把 Nginx 当作执行终端,而非决策中心。
健康检查是前提,不是替代方案
权重只在节点“健康”时生效。一旦节点失联或响应超时,Nginx 会跳过它,此时 weight 再高也无意义。所以必须先配好健康检查:
- 被动检查:在 server 行中加 max_fails=3 fail_timeout=30s,连续失败 3 次后暂停分发 30 秒
- 主动检查(推荐):用 nginx_upstream_check_module 或 OpenResty 的 health_check,定期发 HEAD 或 GET /health 请求验证可用性
- 注意:weight=0 的节点仍参与健康检查,只是不接流量;真正要下线用 down,要备用用 backup
三种可行的自动调权路径
真正实现“健康信息 → 权重变化”,需构建采集、决策、执行闭环。目前生产验证有效的方案有:
- Consul + nginx-upsync-module:后端指标(如 P95 延迟)由 sidecar 上报到 Consul KV;Nginx 每 300ms 拉取 JSON 列表(含 server、weight、max_fails),内存热更新,毫秒级生效
- OpenResty + Lua:用 lua_shared_dict 缓存各节点实时延迟,每 2–5 秒探测一次;在 balancer_by_lua_block 中按公式 weight = base × (ref_rt / actual_rt)² 动态选节点,不 reload、不断连
- nginx-upstream-dynamic-servers + HTTP API:模块提供 REST 接口,外部脚本(如 Python + Prometheus)每分钟拉取指标、重算权重,再 POST 更新:curl -X POST /upstream/servers -d '{"server":"192.168.1.11","weight":6}'
权重调整不能脱离可观测性
没有监控数据支撑的调权就是盲调。上线后必须盯住三项真实指标:
- 后端 access log 中 $upstream_addr 出现频次,确认是否趋近设定比例(数百请求以上才稳定)
- 各节点 P95 响应时间 和 错误率(5xx),若高权重点延迟飙升或错误陡增,说明权重已失准
- 节点 CPU 使用率 和 活跃连接数,避免某台长期满载而其他空闲
别踩这些常见坑
很多团队试过自动调权却效果不佳,往往因为忽略了这些细节:
- 误以为 least_conn 是动态调权——它只看连接数,不感知响应时间或资源负载,和 weight 无关
- 把 ip_hash 和 weight 混用——哈希绑定下 weight 只在故障转移时起作用,日常不生效
- 权重比设成 10:1 或 100:1——放大误差、失去冗余,建议控制在 4:2:1 这类温和梯度内
- 改完配置直接 reload,没跑 nginx -t——weight 写错(如小数、负数)会导致整个代理中断











