一、引言
A/B测试是微服务时代一个非常重要的能力,需求快速迭代上线和发布,必须具备对应的灰度测试的能力,对于上线的内容进行隔离验证,减少频繁变更带来的风险。本文介绍如何使用nginx 实现前端和后端服务A/B测试。
二、使用upstream实现A/B分流
upstream模块实现A/B分流适合后端部署在多个服务器上,有独立的IP和端口的场景,支持多种不同的分发方式,例如轮询、ip_hash、权重,,默认场景下是轮询,以下为使用ip_hash和权重的配置案例:
1、使用ip_hash的方式
upstream app{
ip_hash;
server 192.168.56.11:8080;
server 192.168.56.12:8080;
}
2、使用权重的方式
upstream app{
server 192.168.56.11:8080 weight=1;
server 192.168.56.12:8080 weight=2;
}
使用upstream的方式配置非常简单,但是无法比较精确的控制分流的流量比例,只适合比较粗粒度的
三、使用split_clients实现客户端A/B分流
ngx_stream_split_clients_module是新版的nginx的内置模块,用于提供客户端的分流功能,默认情况下已经被编译进了nginx,如果想要禁用这个模块,可以通过在编译时添加--without-http_split_clients_module参数,模块的语法为:split_clients string $variable { ... }
,以下是配置案例:
split_clients "${remote_addr}AAA"$variant {
10.00% version1;
20.00% version2;
* version3;
}
server{
location / {
index ${variant}/index.html;;
}
}
原理是使用 MurmurHash2 对原始字符串的值进行哈希处理 ,按照配置的比例为variant变量赋值,如上配置所示,部署三个不同的版本,version1分配10%的流量,version2分配20%的流量,*代表100%-10%-20%=70%的流量,如上例所示,在根目录下创建version1、version2、version3三个目录,分别部署不同版本的前端资源,通过location配置不同的的variant值访问不同目录下的index.html,从而达到对于前端应用按照不同的分流比例进行分流访问的目的。
四、使用split_clients实现后端应用A/B分流
以上的示例是实现客户端应用的A/B分流,后端应用同样也需要有A/B测试的能力,一般有两种情况:
- 使用proxy_pass转发到不同的上下文
split_clients "${remote_addr}AAA"$variant {
10.00% version1;
20.00% version2;
* version3;
}
location /test {
proxy_passhttp://192.168.56.12:8080/${variant};
}
- 通过请求头参数,利用API网关等解析参数进行分流
对于不能直接通过proxy_pass转发到不同的上下文的情况,可以通过proxy_set_header将分流后不同的流量带上不同的参数,此参数透传到后端服务,后端服务部署API网关,在API网关上解析对应的参数进行分流,如下所示,将variant变量设置到REQUEST-TYPE中。
split_clients "${remote_addr}AAA"$variant {
10.00% version1;
20.00% version2;
* version3;
}
location /test {
proxy_set_headerREQUEST-TYPE$variant
proxy_passhttp://192.168.56.12:8080;
}
使用ngx_stream_split_clients_module实现A/B分流能够比较精细的控制分流的流量比例,搭配API网关等服务可以实现灵活的控制,是比较建议的方案。