Nginx 通过两层 map 实现纯原生高频路径+用户标识动态分流:首层识别 /api/v1/search 等路径,次层结合 $uid_num 正则匹配(如6位以上数字)路由至 ssd_backend,并严格绑定 upstream 与日志透传。

用 map 变量在反向代理阶段动态分流高频路径用户,核心是把“路径特征 + 用户标识”作为联合判断依据,生成目标后端变量,并精准绑定到 SSD 集群的 upstream。它不依赖 Lua 或外部模块,纯 Nginx 原生配置即可落地。
提取稳定分流维度:路径 + 用户标识组合
高频路径(如 /api/v1/search、/api/v1/feed)本身不足以区分“用户是否高频”,需叠加用户稳定标识。推荐优先使用:
- $cookie_user_id:登录态用户 ID,长期稳定,适合哈希或正则提取
-
$arg_uid:URL 参数透传的用户 ID(如
?uid=123456),前端可控、无 Cookie 依赖 - 避免直接用 $remote_addr:IP 易变,NAT 下不唯一;若必须用,建议配合 CIDR 段粗筛
例如,先从 cookie 中提取数字 UID:
map $cookie_user_id $uid_num {
default "";
~^(\d+)$ "$1";
}
定义高频路径与 SSD 集群的映射规则
用两层 map 实现清晰分层:第一层识别是否命中高频路径,第二层结合用户特征决定是否进 SSD 集群。
map $uri $is_hot_path {
default 0;
~^/api/v1/search/ 1;
~^/api/v1/feed/ 1;
~^/api/v1/recommend/ 1;
}
map "$is_hot_path:$uid_num" $backend {
default "prod_backend";
"1:~^[0-9]{6,}$" "ssd_backend"; <!-- UID 为 6 位及以上数字时走 SSD -->
"1:~^[13579]\d{5}$" "ssd_backend"; <!-- 末位为奇数的 6 位 UID -->
}
说明:第二层 key 是字符串拼接,支持正则匹配子串;"1:~^[0-9]{6,}$" 表示“是高频路径且 UID 至少 6 位”,满足即路由至 ssd_backend。
绑定 SSD 专属 upstream 并启用 proxy_pass
确保 ssd_backend 名称与 map 输出值完全一致(大小写、下划线、拼写),并在 http 块顶部静态声明:
upstream ssd_backend {
server 10.0.3.10:8000 weight=3;
server 10.0.3.11:8000 weight=3;
server 10.0.3.12:8000 max_fails=2 fail_timeout=10s;
keepalive 32;
}
upstream prod_backend {
server 10.0.2.10:8000;
server 10.0.2.11:8000;
}
在 location 中复用变量:
location /api/ {
proxy_pass http://$backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Backend $backend; <!-- 透传用于日志追踪 -->
}
验证与兜底:防 502,留可观测入口
关键三点必须落实:
-
default 必设:所有 map 块都显式写
default "prod_backend",杜绝变量为空导致 502 - upstream 名称严格一致:Nginx 启动时校验,名称错一个字符就启动失败
-
日志中记录分流结果:在 log_format 中加入
$backend字段,便于统计 SSD 集群命中率和用户分布



















