Nginx原生不支持运行时修改upstream weight,动态权重需依赖外部监控(如Prometheus)采集指标、脚本计算新权重,并通过nginx-upsync-module/Consul、OpenResty+Lua或nginx-upstream-dynamic-servers等机制热更新,全程闭环可观测、低延迟、不中断服务。

Nginx 本身不直接采集指标或自动调权,动态调整流量配额必须靠外部监控系统驱动配置更新。核心思路是:用 Prometheus 监控后端真实负载,触发告警或脚本计算新权重,再通过轻量机制(如 API 或配置同步)写入 Nginx,最终由 upstream 生效。整个过程要闭环、低延迟、不中断服务。
用 Prometheus + 告警脚本驱动权重重算
在 Prometheus 中定义关键指标表达式,例如:
-
单节点 P95 延迟:
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, instance)) -
5xx 错误率:
sum(rate(http_requests_total{status=~"5.."}[5m])) by (instance) / sum(rate(http_requests_total[5m])) by (instance) -
活跃连接数占比:
nginx_upstream_active_connections{upstream="backend_pool"} / nginx_upstream_max_conns{upstream="backend_pool"}
配置 Alertmanager 规则,当某节点 P95 超过 800ms 或错误率 > 2% 时,触发 webhook 调用 Python 脚本。脚本根据公式 weight = base × (ref_rt / actual_rt)² 重新计算各节点权重,并通过 HTTP POST 推送至 Nginx 的动态管理接口(如 nginx-upstream-dynamic-servers 提供的 /upstream/servers)。
选对动态更新方案,避免 reload 中断
原生 Nginx 的 weight 是静态参数,reload 才生效,不适合实时调控。推荐三种落地方式:
- nginx-upsync-module + Consul:Nginx 每 300ms 主动拉取 Consul KV 中的 server 列表(含 weight、max_fails、backup 等),故障节点可自动设 weight=0;适合中大型集群,强一致性好
-
OpenResty + Lua 全链路控制:用
lua_shared_dict缓存各节点响应时间与错误率,每 3 秒探测一次业务路径,在balancer_by_lua_block中实时选节点并调用balancer.set_current_peer();适合需要熔断、灰度、AB 测试的场景 -
nginx-upstream-dynamic-servers:无需额外依赖,upstream 块中声明
dynamic_server on;,然后用 curl 控制增删改节点及权重;适合中小集群快速上线
权重设定要讲逻辑,不是拍脑袋
weight 不是开关,而是容量锚点。比如 16 核服务器设 weight=8,8 核设 weight=4,理论承接比就是 2:1。实操建议:
- 新节点上线从
weight=2起步,防冷启动冲击 - 维护前逐步降到
weight=2,让流量自然倾斜 - 避免用极端值(如 100 和 1),误差会被放大
- 必须搭配
least_conn和max_conns,否则高权重点堆积长连接时仍会持续收请求
监控闭环决定调权是否有效
没有可观测性,调权就是盲调。除了基础指标,重点关注:
-
nginx_upstream_active_connections:持续接近
max_conns,说明已到瓶颈 - nginx_upstream_fails:某节点失败次数突增,需检查网络或应用层
- nginx_upstream_header_time:区分是 Nginx 转发慢,还是后端处理慢
把这些指标接入 Grafana,设置阈值告警面板,和权重调整动作形成反馈回路——这才是真正可用的动态流量配额体系。











