nginx split_clients模块通过一致性哈希实现稳定a/b分流,需基于uid cookie等稳定标识、避免空值、用整数区间精确控制比例,并配合upstream路由和运行时开关机制保障灰度可控。

使用 Nginx 的 split_clients 模块可实现无状态、低开销的 A/B 测试流量分流,关键在于确保分流结果稳定、可复现且符合预设比例。
分流逻辑必须基于稳定标识符
直接用随机数会导致每次请求重新计算,无法保证同一用户持续访问同一版本。应基于客户端可稳定获取的字段(如 Cookie、IP 或 User-Agent 哈希)做一致性哈希:
- 推荐优先使用业务已有的用户标识(如
uidCookie),例如:
split_clients "$cookie_uid" $variant { - 若无登录态,可用 IP 做近似识别,但需注意 NAT 场景下多个用户共用 IP 的偏差;
- 避免单独依赖
$remote_addr,建议组合端口或哈希增强离散度,如"$remote_addr:$remote_port"; - 所有输入值需做非空 fallback,例如
"${cookie_uid}000"防止空字符串导致哈希坍缩。
配比精度靠区间划分而非概率抽样
split_clients 本质是将哈希值映射到 0–999999 区间,再按预设范围分配变量值,因此实际比例由区间长度严格决定:
- 要实现 70% / 30%,应写为:
700000 A;
1000000 B; - 切勿写成
0.7 A; 1.0 B;—— 模块不支持浮点,会截断为0 A; 1 B;导致 100% 分到 A; - 多组实验(如 A/B/C)需累加区间:A(0–499999)、B(500000–799999)、C(800000–999999)对应 50%/30%/20%;
- 上线前用小流量验证实际分布,可通过日志统计
$variant出现频次校准。
与 upstream 协同实现后端路由隔离
分流变量仅是标记,需配合 proxy_pass 实际转发到不同服务集群:
- 定义两套 upstream(如
backend_v1和backend_v2),配置健康检查与负载策略; - 在 location 中根据
$variant选择目标:
proxy_pass http://backend_$variant; - 务必开启
proxy_redirect off;和proxy_set_header Host $host;,避免后端感知异常; - 对静态资源或 CDN 回源路径,同样需透传或重写
variant参数,确保前端 JS 也能读取当前分组。
灰度与回滚需有明确开关机制
生产环境不能依赖配置热重载做紧急切换,应设计运行时可控的降级路径:
- 用 map 指令覆盖
split_clients结果,例如通过共享字典或外部配置中心下发开关; - 预留强制指定参数(如
?ab=force_a),在 location 中优先匹配 query string 并 set $variant; - 记录每个请求的
$variant、原始标识、时间戳到独立 access_log,便于问题定位与归因分析; - 监控维度至少包括:各 variant 的 QPS、错误率、平均延迟、转化率,出现显著负向时自动告警并触发人工干预。










