多上游模型权重路由,根据用户等级分配不同模型优先级
多上游模型权重路由,是网关或代理层按用户等级把请求分发到不同大模型的一种策略。
比如普通用户优先走价格低的轻量模型,付费会员走旗舰模型,这就是把用户等级映射为权重和优先级。
本文直接用可运行的 Nginx 与 OpenResty 场景做示范,零基础也能照着配。
动手前先把用户等级与模型池理清楚
配置这类路由前,你要先确认三件事:
- 用户等级怎么传入上游:通常由登录态解析出等级参数,通过自定义请求头传给网关,例如
X-User-Tier: gold。配置时先固定这个字段名方便统一管理。 - 上游模型地址具有可访问性:每个模型服务必须可以被当前服务器访问,建议先用
curl单独验证连通性,确认返回正常再接入路由规则。 - 路由要可回退:当高等级模型超时、过载或返回 5xx 时,能自动降级到低一级模型,避免请求直接失败。
这里说的“权重”,不只是字面意义的负载均衡比重,更代表模型处理的优先顺序。
可以把它理解成:当多个上游可用时,网关优先把请求发给哪一档模型。
推荐方案:OpenResty 用 Lua 做分级路由
如果希望做条件判断,OpenResty 比纯 Nginx 更适合。
下面示例假设上游名称为:model_basic、model_pro、model_flagship,分别对应三个模型服务地址。
先打开 nginx.conf 中的 http {} 块,定义一组上游:
upstream model_basic {
server 10.0.0.11:8000 max_fails=2 fail_timeout=30s;
}
upstream model_pro {
server 10.0.0.12:8000 max_fails=2 fail_timeout=30s;
}
upstream model_flagship {
server 10.0.0.13:8000 max_fails=2 fail_timeout=30s;
}
然后在 server {} 中通过 access_by_lua_file 引入路由逻辑。
新建 /etc/nginx/lua/model_tier_router.lua:
local balancer = require "ngx.balancer"
local tier = ngx.var.http_x_user_tier or "normal"
local route_rules = {
premium = {
primary = "model_flagship",
fallback = "model_pro"
},
member = {
primary = "model_pro",
fallback = "model_basic"
},
normal = {
primary = "model_basic",
fallback = nil
}
}
local rule = route_rules[tier] or route_rules["normal"]
local selected = rule.primary
if not balancer.set_current_peer(...) then
-- 实际项目中需先解析 pool 的 peer,这里用于保留降级逻辑
selected = rule.fallback or rule.primary
end
-- 根据所选上游名称设置对应地址,这里简化为写日志并转发
ngx.log(ngx.INFO, "tier=", tier, " selected=", selected)
这段只是路由判断骨架。
真正落地时建议使用 balancer_by_lua 并在该阶段调用 balancer.set_current_peer,优先选择主模型,如果主模型不健康则把请求切换到备选模型。
纯 Nginx 加权重也能实现近似效果
不想引入 Lua 时,可以通过变量匹配多个 server 块来实现分级转发。
先给用户等级打标记:
map $http_x_user_tier $backend_pool {
default basic;
premium flagship;
member pro;
}
upstream basic { server 10.0.0.11:8000; }
upstream pro { server 10.0.0.12:8000; }
upstream flagship { server 10.0.0.13:8000; }
但 Nginx 不允许在上游名称中直接使用变量。
所以更适合写成多个 location:
location /v1/chat/completions {
set $upstream_name $backend_pool;
if ($upstream_name = "flagship") {
proxy_pass http://model_flagship;
}
if ($upstream_name = "pro") {
proxy_pass http://model_pro;
}
if ($upstream_name = "basic") {
proxy_pass http://model_basic;
}
}
这种方式优点是简单,但需要重点确认:proxy_pass 放在 if 块内部时,某些旧版本 Nginx 会产生限制。
生产环境建议将版本固定并先在测试环境跑通。
用权重参数做灰度平滑切换
如果只想让 10% 的会员流量先试旗舰模型,可以给两个上游配一个入口,通过哈希或随机数决定会话级别:
map $remote_user $model_pool {
default "model_basic";
~^VIP "model_pro";
}
然后在 Lua 里按用户 ID 的 hash 值做灰度阈值:
local hash = ngx.crc32_short(user_id)
if hash % 100 < 10 then
-- 会员走 flagship 灰度
end
灰度期间必须检查下游模型的实际耗时与错误率,不要只依赖代码里写的权重和阈值,因为模型服务的性能变化会直接影响最终体验。
避坑指南:权重路由最常见的三个坑
第一,上游名称写错却不会报错。
比如把 model_pro 写成 model_pro_1,Nginx 加载时不报错,但请求找不到主机名才会显示 502。
配置后必须用 nginx -t 检查并实际请求一次。
第二,业务侧没有传用户等级头。
如果从请求中拿不到等级,最终所有人都落在默认档位。
建议配置文件里写默认值,但也要在日志中记录真实收到的请求头,方便核对。
第三,缺少超时保护。
旗舰模型推理往往更慢,建议将 proxy_read_timeout 设置为 120s 或更长,并加入健康检查逻辑。
上游群组当前没有主动健康检查时,可用 nginx_upstream_check_module 或依赖 max_fails/fail_timeout 做被动检查。
如何验证模型优先级确实生效
配置完成后,验证必须分三步走。
先执行配置检查:
nginx -t
systemctl reload nginx # 实际命令以你的发行版为准
再用不同等级请求,逐一看落地节点:
curl -H "X-User-Tier: normal" http://你的域名/v1/chat/completions -d '{"prompt":"hi"}'
curl -H "X-User-Tier: member" http://你的域名/v1/chat/completions -d '{"prompt":"hi"}'
curl -H "X-User-Tier: premium" http://你的域名/v1/chat/completions -d '{"prompt":"hi"}'
观察网关日志中打印的 selected 字段,确认普通用户落在 model_basic,会员落在 model_pro,高价值用户落在 model_flagship。
更准确的方法是给三个模型各返回带标识字段的响应体,日志结合响应体双重确认。
如果请求返回 502,重点检查对应上游地址是否可达;
如果返回 400,说明请求头或 body 格式没被正确透传。
想看更详细调试信息时,可在 Lua 脚本中临时增加 ngx.log,分析完再关闭,不要带着调试日志直接上线。
结合实践,这套配置适合两类人:一类是已经搭建了模型网关想完善路由策略的运维,另一类是准备上线多模型产品、需要从起步阶段就规划好用户分级的使用方。
根据自己网关类型选择 Lua 方案或纯 Nginx 方案即可。
多上游模型权重路由的核心不在代码多复杂,而在于等级字段能稳定传入、路由规则能分级回退、每档上游能得到可观测的指标,做到这三点就能稳定跑起来。