通常情况下,我们在开发新版本的代码,并将它发布到集群中,我们会将现网一小部分用户的访问引流到新版本,用来验证产品的体验以及发现bug第二个。通常我们会做A/B测试,A/B测试能够让我们深入了解用户的行为。由于我的集群是k8s,我使用nginx作为我的ingress controller实现,这里我们主要谈怎么使用nginx实现这个功能。nginx提供了“nginx_http_split_clients_module”、“nginx_stream_split_clients_module”分别简单实现了http和tcp的这些功能。

为此,专门去nginx官网查看了nginx_http_split_clients_module(nginx_stream_split_clients_module同理)的用法

http {
    split_clients "${remote_addr}AAA" $variant {
                   0.5%               .one;
                   2.0%               .two;
                   *                  "";
    }

    server {
        location / {
            index index${variant}.html;

使用一个变量做A/B测试,这里使用每个访问的客户端addr做变量

split_clients "${remote_addr}AAA" $variant {
               0.5%               .one;
               2.0%               .two;
               *                  "";
}

这个配置的意思是说,如果假如请求的addr为192.168.1.110,那么就将192.168.1.110AAA经过MurmurHash2(总范围为0 ~ 2^32 - 1),如果这个结果落在0 到21474835 (0.5%),那么variant 变量的值为.one,如果这个运算的结果落在21474836到107374180 (2%),那么variant变量的值为.two,其它情况为空值,则最后location的值为index.one.html、index.two.html或index.html,这样看来我们是实现了根据不同用户特征去实现了请求的分流,最终请求落到不同的应用上,也实现了我们的A/B测试。

通常这时候我们的需求完成了,但是他却不能给用户持久的体验(和我们选取的动态字段有关)。

如果我们刷新网页,这可能再多个空间中切换,这个可能是一种可怕的用户体验。想象这样一种情景,如果用户的一个请求是返回6个字段的信息,如果刷新下页面,只看到2个字段的信息,这时候用户也会凌乱的。

一个更佳的方法:

1、请求可以代理到任意空间
2、设置cookie,给定一个期限做测试
3、检测cookie是否能够按照正确的方式代理到指定的空间,从而确保统一的用户体验。

这里需要使用到nginx的map指令,并设置$cookie_name变量映射到我们创建的不同的空间。这里我们假设有两个版本的应用,他们的服务端口分别为8888和9999,我们使用nginx给这两个版本做A/B测试,具体的配置如下

http {
    # ...
    upstream old{
        server server 192.168.1.100:8888; 
    }

    upstream new{
        server server 192.168.1.100:9999;
    }
    split_clients "app${remote_addr}${http_user_agent}${date_gmt}"    $appversion {
        80%     old;
        *       new;
    }
    map $cookie_test_version $upstream_group {
        default $appversion;
        "old"  "old";
        "new" "new";
    }
	server {
        listen 80;
        location / {
            add_header Set-Cookie "test_version=$upstream_group;Path=/;Max-Age=518400;";
            proxy_set_header Host $host;
            if ($upstream_group = "old") {
                proxy_pass http://192.168.1.100:8888;
                break;
            }
          if ($upstream_group = "new") {
                proxy_pass http://192.168.1.100:9999;
                break;
            }
          proxy_pass http://$appversion;
        }
    }
}

总结

这里提供了一个非常简单的api来完成A/B测试环境,这里我们后端有多少个版本的应用,我们就可以创建多少空间,通过cookie我们就解决了版本的随意切换问题。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐