split_clients通过哈希$uid_for_split实现用户级稳定灰度分流,需用Header/Cookie中可靠用户ID(非$remote_addr)作输入,配合map兜底、加权白名单及日志追踪确保精准可控。

split_clients 是 NGINX 的核心模块(自 1.11.3 起支持 HTTP 和 Stream 层),它通过哈希算法将请求稳定映射到指定分组,适合做可重复、无状态、用户粒度一致的灰度分流。但要注意:它本身不解析用户身份(如 user_id 或登录态),必须配合 $http_x_user_id、$cookie_uid 等变量使用,才能实现真正基于用户特征的路由。
✅ 正确配置 split_clients 实现用户特征灰度
关键不是“用不用”,而是用什么字符串做哈希输入。若直接用 $remote_addr,就只是按 IP 分流,无法保证同一用户跨设备/网络时路由稳定。
1. 提取可靠用户标识
在 http 块中定义变量,优先级从高到低建议:
-
首选:Header 中透传的用户 ID(如
X-User-ID)map $http_x_user_id $uid_for_split { "" $remote_addr; # 未传时降级为 IP(兜底) default $http_x_user_id; } -
次选:Cookie 中的 uid(需 base64 或数字格式,避免特殊字符)
Skill Weave Chains — 技能链路由引擎下载开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
map $cookie_uid $uid_for_split { "" $remote_addr; default $cookie_uid; }
⚠️ 注意:
split_clients对输入字符串敏感,含空格、中文、斜杠等会导致哈希结果异常。建议后端统一传递纯数字或 base64 编码的 ID。
2. 使用 split_clients 绑定用户 ID 到版本
split_clients "$uid_for_split" $app_version {
5% "v2"; # 5% 用户固定命中 v2
95% "v1"; # 其余走 v1
}- 每个用户(由
$uid_for_split唯一确定)会永久落在同一分组(MurmurHash2 + 取模),不会因请求时间、路径变化而跳变。 - 比例修改后 reload 即可生效,无需重启。
3. 在 location 中按版本转发
upstream backend_v1 { server 10.0.0.1:8080; }
upstream backend_v2 { server 10.0.0.2:8080; }
server {
listen 80;
location /api/ {
proxy_set_header X-App-Version $app_version;
if ($app_version = "v2") {
proxy_pass http://backend_v2;
break;
}
proxy_pass http://backend_v1;
}
}- 推荐把
$app_version透传给后端,便于日志追踪和业务逻辑判断。 - 不要用
rewrite或多层if嵌套,避免执行顺序问题;proxy_pass应直接基于$app_version决策。
❌ 常见错误与规避方式
错误:用
$args或$request_uri当哈希源
→ URL 参数易变(如带时间戳、随机数),导致同一用户反复切换版本。错误:在
if中动态读取 Header 后再计算比例
→split_clients是编译期绑定,不能运行时调用函数。所有逻辑必须提前用map或变量准备好。错误:未设置兜底值,
$uid_for_split为空时哈希结果不可控
→ 必须在map中明确""的映射,例如指向$remote_addr或固定字符串"anonymous"。错误:认为 10% 流量 = 10% 用户
→ 若用户 ID 分布极不均匀(如大量请求来自少数爬虫 ID),实际覆盖用户数可能远低于预期。此时应配合白名单或业务规则补充。
? 进阶建议:提升精准度与可观测性
-
加权白名单支持
map $http_x_user_id $app_version { default "v1"; "~^100[1-5]$" "v2"; # 用户 ID 为 1001~1005 强制走 v2 "~^admin.*$" "v2"; }map规则优先级高于split_clients,适合定向灰度。 -
记录灰度决策日志
log_format gray '$remote_addr - $uid_for_split → $app_version "$request"'; access_log /var/log/nginx/gray.log gray;
与 OpenTracing 结合
在proxy_set_header中注入X-Trace-ID和X-App-Version,确保全链路可追溯。
不复杂但容易忽略


















