split_clients指令通过MurmurHash2哈希+取模实现确定性分流,输入变量拼接确保唯一性,5%“v2”/95%“v1”按0–4与5–99阈值分配,结果变量可直接用于header、proxy_pass或upstream路由。

使用 split_clients 指令可以在 Nginx 的 http 块中实现基于请求特征的确定性流量分流,适合轻量级、无状态的 A/B 测试场景。它的核心优势是不依赖外部存储、无请求延迟、结果可复现——同一用户(满足条件时)始终命中同一分组。
split_clients 的基本原理与语法结构
split_clients 通过哈希 + 取模方式将输入值映射到预设百分比区间,生成稳定的整数标识(如 0~99),再按阈值划分 bucket。关键点:
- 输入可以是任意变量(如
$arg_uid、$cookie_abtest_id、$remote_addr),但必须是字符串; - 哈希算法固定为 MurmurHash2,结果对相同输入恒定;
- 每个
percent表示该 bucket 覆盖的哈希值范围(0–99 整数),累加需等于 100; - 生成的变量在后续配置中可直接引用,例如用于设置 header、proxy_pass 或 rewrite。
典型 A/B 分流配置示例
假设需将 5% 用户导流至新版本服务(v2),其余走默认(v1),并确保登录用户按 UID 稳定分流:
split_clients "$arg_uid$cookie_abtest_id$remote_addr" $ab_version {
5% "v2";
* "v1";
}说明:
- 拼接多个变量增强唯一性,避免单一变量为空导致哈希碰撞;
-
5%对应哈希值 0–4(含),*匹配剩余 5–99; - 变量
$ab_version在 location 中可直接使用,例如:proxy_set_header X-AB-Version $ab_version;
或配合 map 实现更灵活路由:proxy_pass http://backend_$ab_version;
保证分流稳定性的关键实践
要让同一用户始终进入同一分组,必须确保输入字符串具备「用户粒度唯一性」和「跨请求一致性」:
- 优先使用业务侧下发的稳定 ID(如
$arg_uid或$cookie_user_id),避免仅用$remote_addr(NAT/代理下不准确); - 若无 UID,可用加密 cookie(如
$cookie_ab_seed)+ fallback 机制:首次请求生成并 Set-Cookie,后续读取; - 注意变量为空时的哈希行为:空字符串参与哈希会降低区分度,建议拼接默认值(如
"$arg_uid-unknown"); - 上线前用脚本模拟哈希分布(Python + mmh3 库),验证各 bucket 实际占比是否符合预期。
与 upstream 配合实现后端隔离路由
将分流结果映射到不同 upstream 组,实现真正的服务隔离:
upstream backend_v1 { server 10.0.1.10:8080; }
upstream backend_v2 { server 10.0.1.11:8080; }
<p>split_clients "$cookie_user_id$arg_uid" $upstream_group {
5% "v2";</p><ul><li><pre class="brush:php;toolbar:false;"> "v1";}
server { location / { set $backend "backend_$upstream_group"; proxy_pass https://www.php.cn/link/7c677ff4c58e458338c5f7e74556735d; } }
注意:proxy_pass 中使用变量需启用 resolver(若用域名)或改用 map + upstream 静态定义(推荐),避免运行时解析开销。

















