split_clients模块通过一致性哈希实现无状态ab测试流量切分,基于$remote_addr等变量md5取模映射0–999999范围,按预设权重(如0.10“v2”;*“v1”)分配用户至不同后端,保证同一用户始终归属相同分组。

nginx 的 split_clients 模块是实现轻量级、服务端 AB 测试流量切分的高效方式,无需依赖外部组件或修改应用逻辑。它基于请求的某个可预测字段(如 $remote_addr、$cookie_uid、$http_user_agent 等)做一致性哈希,将用户稳定地分配到不同后端组,保证同一用户在多次请求中始终落在同一实验分组。
核心原理:确定性哈希 + 预设权重
split_clients 不是随机打散,而是对指定变量做 MD5 哈希后取模,映射到 0–999999 范围内的整数,再按预设区间划分流量比例。这种机制确保:
- 相同输入(如固定 IP 或 Cookie)永远得到相同分组,用户实验体验不跳变
- 无需维护状态或会话存储,完全无状态,适合高并发场景
- 权重配置直观,例如 5% / 95%、20% / 20% / 60%,支持最多 100 个分组(实际常用 2–4 个)
基础配置示例:按 IP 做 10% 新版流量切分
以下配置将约 10% 的真实用户(以客户端 IP 为依据)路由到新版本后端 backend_v2,其余走默认 backend_v1:
split_clients "${remote_addr}" $version_group {
0.10 "v2";
* "v1";
}
<p>upstream backend_v1 {
server 10.0.1.10:8080;
}</p><p>upstream backend_v2 {
server 10.0.1.11:8080;
}</p><p>server {
listen 80;
location / {
proxy<em>pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a></em>$version_group;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}</p>说明:
• "${remote_addr}" 是哈希源,也可换为 $cookie_ab_test_id 或 $arg_utm_source 等;
• 0.10 表示前 10% 的哈希值(即 0–99999)分配给 "v2";
• * 是兜底规则,覆盖剩余 90%;
• 变量 $version_group 在后续 proxy_pass 中直接拼接使用,简洁可靠。
进阶用法:多维度可控切分
实际 AB 测试常需更精细控制,例如:
-
排除内网和爬虫:先用
map过滤无效流量,再进split_clients -
按用户标识切分:优先使用登录态 Cookie(如
$cookie_uid),比 IP 更准确且跨设备一致 -
灰度+白名单叠加:用
if ($args ~* "ab_force=v2") { set $version_group "v2"; }强制指定,便于人工验证 -
记录分组信息:添加
proxy_set_header X-AB-Group $version_group;,方便后端和日志分析
注意事项与排障要点
该模块看似简单,但易踩几个坑:
-
split_clients必须定义在http块顶层,不能放在server或location内 - 哈希变量若为空(如未携带指定 Cookie),会被当作空字符串处理,导致大量用户挤进同一分组 —— 建议配合
map提供默认值 - 权重总和不必严格等于 100%,nginx 按顺序匹配首个满足条件的分支,
*应放在最后 - 修改配置后需
nginx -t && nginx -s reload,不重启 worker 进程,不影响线上流量











