split_clients 是 Nginx 轻量级哈希分流模块,基于客户端变量(如 IP、Cookie)做确定性 MD5 哈希与范围映射,实现稳定灰度/A/B 测试;需编译启用,无状态、不支持热更新,适合网关层前置路由。

split_clients 是 Nginx 官方提供的一个轻量级模块(需在编译时启用 --with-http-split-clients-module),专用于根据客户端标识(如 IP、User-Agent、请求头等)做**确定性哈希分流**,实现稳定、可复现的流量比例分配。它不依赖外部服务,无状态,适合做灰度发布或 A/B 测试的底层路由控制。
核心原理:哈希 + 范围映射
split_clients 会对指定变量(如 $remote_addr)进行 MD5 哈希,取结果的前 32 位转为整数(0–4294967295),再按预设百分比区间映射到不同 upstream 或变量值。关键点是:同一客户端每次请求都命中同一分组,保证会话一致性。
例如:
split_clients "$remote_addr" $backend {
10% backend_a;
20% backend_b;
70% backend_c;
}
这里 Nginx 将哈希值划分为 [0, 429496729) → backend_a(10%)、[429496729, 1288490187) → backend_b(20%)、其余 → backend_c(70%)。
典型 A/B 测试配置示例
假设你有两版前端服务(v1 和 v2),希望按 50/50 比例对真实用户分流,并记录分组信息供后端或日志分析:
- 使用
$remote_addr作为分流键 —— 简单可靠,但注意 NAT 场景下可能多个用户共用 IP;更精细可选$http_x_real_ip(需可信代理设置)或$cookie_ab_test_id(前端主动透传唯一 ID) - 定义 split_clients 块,生成变量
$ab_group - 在 location 中通过
proxy_pass或return路由到对应 upstream - 用
add_header或log_format输出分组信息,便于验证和分析
完整配置片段:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
split_clients "$cookie_ab_test_id$remote_addr" $ab_group {
50% "v1";
* "v2";
}
<p>upstream backend_v1 {
server 10.0.1.10:8080;
}
upstream backend_v2 {
server 10.0.1.20:8080;
}</p><p>server {
listen 80;
location / {
add_header X-AB-Group $ab_group;
proxy_set_header X-AB-Group $ab_group;</p><pre class="brush:php;toolbar:false;"> if ($ab_group = "v1") {
proxy_pass http://backend_v1;
break;
}
if ($ab_group = "v2") {
proxy_pass http://backend_v2;
break;
}
proxy_pass http://backend_v1; # fallback
}
}
注意事项与避坑指南
该模块看似简单,实际使用中容易忽略几个关键细节:
-
变量必须存在且非空:若
$cookie_ab_test_id为空,Nginx 会退化为只用$remote_addr;若两者都为空,哈希结果恒定,所有请求分到同一组。建议加默认兜底或前端确保 ID 可控 -
百分比总和不必为 100%:最后一项可用
*表示“其余所有”,适合预留灰度通道(如 95% v1 + 5% v2,再加*给内部测试用) - 不支持运行时热更新比例:修改百分比需 reload Nginx,不适合秒级动态调权;高频调整建议结合 Lua 或 OpenResty
-
无法做用户级行为追踪:仅分流,不收集点击/转化等指标;需配合前端埋点 + 后端日志(如通过
X-AB-Group关联)完成闭环分析
进阶技巧:组合使用提升灵活性
单一 split_clients 功能有限,常需搭配其他模块增强能力:
- 与 map 模块嵌套:先用 split_clients 生成粗粒度分组(如 region),再用 map 根据 UA 或设备类型做二次细分
- 与 geo 模块协同:对国内 IP 固定走 v1,海外 IP 再按 50/50 分流,实现地域+随机双维度策略
- 与 lua-resty-balancer 配合:在 init_by_lua_block 中读取 Redis 配置,动态生成 split_clients 规则字符串(需定制编译或改用 OpenResty)
不复杂但容易忽略:分流逻辑越前置(如 L7 网关层),对业务侵入越小;而把 AB 判断放到应用层,往往导致重复开发和一致性难题。










