多维度架构设计之灰度测试方案
A/B测试 vs 灰度测试 vs 蓝绿部署 vs 金丝雀发布
A/B测试 vs 灰度测试 vs 蓝绿部署 vs 金丝雀发布概念类似,手段类似,只是侧重点不同。
它们都需要两套环境,用户被主动或被动地分配到这两套环境中的一套上去。
什么是灰度测试?
灰度测试是指将产品/产品新功能,少量给一部分目标人群使用,通过用户的反馈结果来决定是否进一步扩大用户群,直到这个新功能覆盖所有用户,灰度测试能用最少的试错成本收集用户反馈,并及时修改产品的一些不足和缺陷,完善产品的功能,使产品的质量得到提高。
解决方案
灰度测试解决方案有很多,并自由统一的标准,只要最终实现需求,达到效果即可。
这里的解决方案使用的是 Openresty
lua_shared_dict cache 128m; lua_shared_dict upstream 1m; upstream production { server 192.168.0.2:80; } upstream grey { server 192.168.0.3:80; } upstream balance { server 192.168.0.2:80; server 192.168.0.3:80; } server { listen 80; listen 443 ssl http2; server_name www.netkiller.cn; ssl_certificate /etc/nginx/cert/netkiller.cn.pem; ssl_certificate_key /etc/nginx/cert/netkiller.cn.key; ssl_session_cache shared:SSL:20m; ssl_session_timeout 60m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; error_log logs/lua.log notice; location / { set_by_lua_file $proxy_pass_url lua/grey.lua; proxy_redirect off; #proxy_set_header Host $host; proxy_set_header Host www.netkiller.cn; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://$proxy_pass_url; } location /grey/get { content_by_lua_file lua/get.lua; } location /grey/set { content_by_lua_file lua/set.lua; } location /grey/del { content_by_lua_file lua/del.lua; } location /grey/switch{ content_by_lua_file lua/switch.lua; } location /grey/check { content_by_lua_file lua/check.lua; } location /grey/log { content_by_lua_file lua/log.lua; } location /grey/debug{ set_by_lua_file $hit lua/grey.lua; echo $hit; } location /nacos { proxy_set_header Host www.netkiller.cn; proxy_pass http://grey; } }
[root@netkiller ~]# cat lua/check.lua json = require("cjson") local cache = ngx.shared.cache local args = ngx.req.get_uri_args() local platform = args['platform'] local city = args['city'] local uid = args['uid'] local result = nil local status = false local data = {} data["data"] = {} if platform and platform ~= "" then result = cache:get("platform" .. platform) if result and result ~= "" then status = true end else if city and city ~= "" then result = cache:get("city" .. city) if result and result ~= "" then status = true end end if uid and uid ~= "" then result = cache:get("uid" .. uid) if result and result ~= "" then status = true end end end if status then data["code"] = 200 data["msg"] = "SUCCESS" data["data"]["environment"] = 'grey' else data["code"] = 400 data["msg"] = "FAILURE" data["data"]["environment"] = 'production' end json_string = json.encode(data) ngx.log(ngx.NOTICE, "upgrade: ", "\"".. json_string .."\"") ngx.header['Content-Type'] = 'application/json; charset=utf-8' ngx.say(json_string)
[root@netkiller ~]# cat lua/del.lua local cache = ngx.shared.cache local args = ngx.req.get_uri_args() local status, err, forcible = cache:delete(args['key'] .. args['value']) ngx.header['Content-Type'] = 'application/json; charset=utf-8' json = require("cjson") data = {} data["status"] = status data["key"] = args['key'] data["value"] = args['value'] json_string = json.encode(data) ngx.say(json_string) ngx.log(ngx.NOTICE, "det: ", json_string)
[root@netkiller ~]# cat lua/get.lua local cache = ngx.shared.cache local args