split_clients无法直接读取Cookie值,因其仅支持变量哈希分流;需先用map将$cookie_ab_test标准化为非空字符串$ab_test_key,再作为split_clients输入源,确保AB分组稳定一致。

split_clients 不能直接读取或匹配 Cookie 值,它只支持基于变量(如 $remote_addr、$args)做哈希分流;想靠 Cookie 实现稳定 AB 分组,必须先把 Cookie 提取到一个变量里,再喂给 split_clients。
为什么 split_clients 看不见你的 Cookie
Nginx 的 split_clients 模块在初始化阶段就完成哈希计算和分组映射,此时请求尚未进入 rewrite 阶段,$cookie_xxx 变量虽存在但未被解析为真实值(尤其当 Cookie 含特殊字符或空格时更易出错)。常见现象是所有用户都被分到同一组,或分组完全随机无一致性。
-
split_clients内部不执行正则匹配,也不支持 if 判断,只认“变量原始字符串”做 MurmurHash2 - 若 Cookie 未设置 HttpOnly 或被前端覆盖,
$cookie_ab_test可能为空,导致哈希结果恒为 0 - 浏览器多标签页、重定向、CDN 缓存可能让同一个用户拿到不同 Cookie,破坏分流稳定性
如何把 Cookie 安全喂给 split_clients
必须用 map 提前将 $cookie_ab_test 标准化为非空、可哈希的字符串,再作为 split_clients 的输入源。
map $cookie_ab_test $ab_test_key {
"" "$remote_addr$uri";
default "$cookie_ab_test";
}
split_clients "$ab_test_key" $ab_version {
50.0% "v1";
50.0% "v2";
}
- 第一行
""分支防止空 Cookie 导致哈希坍缩,用$remote_addr$uri保底(注意:该组合在 CDN 后可能退化为同一 IP,慎用于高并发场景) -
default分支直接透传原始 Cookie 值,确保相同 Cookie 总是得到相同哈希结果 - 不要用
$http_cookie—— 它是原始 Header 字符串,含多个键值对,哈希结果不可控
AB 测试生效前必须确认的三件事
光配对 split_clients 和 map 不够,下游服务必须能感知并响应分组结果,否则流量白分。
- 通过
proxy_set_header X-Ab-Version $ab_version把分组透传给后端,避免后端自己再解析 Cookie - 静态资源(JS/CSS/图片)若也走 AB 路由,需在
location块中显式启用split_clients上下文(默认只在 http/server 级生效) - 首次访问没 Cookie 时,需由后端生成并 Set-Cookie,且该 Cookie 必须带
Path=/和合适Max-Age,否则下次请求无法复用分组
真正难的不是写这几行配置,而是验证每个用户是否在多次请求中始终命中同一分组 —— 建议用 curl 加 -b "ab_test=v1" 手动构造请求,再查 Nginx access_log 里的 $ab_version 字段,别信浏览器开发者工具里看到的“看起来一样”。











