openresty通过balancer_by_lua_block实现upstream权重动态计算,依据用户等级、路径、地域及后端健康度实时调整流量占比,无需reload;支持灰度发布、负载感知调权与热更新配置。

OpenResty 能让 Nginx 的 upstream 权重真正“动起来”——不是靠 reload 配置改死值,而是根据实时业务信号(如用户等级、请求路径、地域、甚至后端健康度)动态计算每个 upstream 组的流量占比,并在每次请求中即时生效。
核心思路:用 Lua 替代静态 weight 指令
Nginx 原生 upstream 的 weight 是编译期固定值,无法运行时调整。OpenResty 的解法是绕过它,改用 balancer_by_lua_block 手动选择目标 peer,并通过加权随机算法模拟权重效果:
- 不给 upstream 块里的 server 设 weight,只作逻辑分组(如
backend_v1、backend_v2) - 在
balancer_by_lua_block中读取当前请求上下文(如ngx.var.arg_version或ngx.var.cookie_uid) - 查 shared_dict 获取最新权重配置(例如
ngx.shared.weights:get("v2_weight")返回 30) - 用加权轮询或加权随机选一个后端地址,调用
balancer.set_current_peer(ip, port)
按用户 ID 动态加权分流
适合灰度发布场景:VIP 用户全量走新版本,普通用户按比例分配,新注册用户固定走旧版。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 定义两个 upstream 组:
upstream backend_old { server 10.0.1.10:8080; }和upstream backend_new { server 10.0.2.10:8080; } - 在
access_by_lua_block中解析 uid,查 Redis 或 shared_dict 判断用户类型 - 为不同用户类型预设权重映射:
{ vip = 100, normal = 20, new_user = 0 } - 生成 [0, 100) 区间随机数,若
rand 则选 new_backend,否则 old_backend - 把结果存入
ngx.ctx.backend_name = "backend_new",供后续 proxy_pass 使用
按接口路径 + 实时负载动态调权
真实生产中,/order/create 比 /user/profile 更耗资源,可对高优路径自动提升新版本权重。
- 用
log_by_lua_block记录每个 upstream 的响应时间与错误率,聚合到 shared_dict - 在
balancer_by_lua_block中读取ngx.var.uri,匹配路径前缀 - 若命中 /order/,则从
weights:get("order_v2_weight")取值(如 75);若为 /user/,则取 10 - 结合当前后端平均延迟(从 shared_dict 读),延迟每高 50ms,权重自动降 5%,避免雪崩
热更新权重配置,无需 reload
运维可通过 HTTP 接口实时调整权重,OpenResty 自动生效:
- 暴露 Admin API:
location /api/upstream/weight { content_by_lua_file /usr/local/nginx/lua/set_weight.lua; } -
set_weight.lua解析 JSON body(如{"v2_weight": 45}),写入ngx.shared.weights - 所有 worker 进程共享该 dict,下次请求即按新权重计算
- 配合定时器定期刷新权重(如从 Consul KV 或数据库拉取),实现全自动策略同步










