平台项目迭代发布过程中,有一些功能发布时会产生较大的影响,一旦出现问题,会影响用户使用体验,降低产品信誉。为了解决这一问题,在重要功能发布时需要引入灰度发布功能,借助一小部分用户在生产环境进行功能的验证,平稳运行一段时间,一般是一周后再大规范应用到生产环境的所有用户。
基于nginx+lua(openresty)可以在nginx网关上进行灵活的业务逻辑处理,本文也使用openresty实现。常见的灰度发布是对指定ip网段进行特定的路由处理,但是公司内网的某个网段范围仍然较大,涉及人员较多,本文使用平台管理员(二十多个用户)作为灰度用户,让“自己人”先验证一下重要功能。由于openresty难以获取请求的用户信息,所以需要在header中加入用户信息,仅用在灰度功能,不存在用户信息泄露的安全问题。Openresty实现灰度功能流程图如下图所示:
?灰度实现逻辑功能代码如下所示:
upstream portalBackend {
server 10.1.1.1:8081;
server 10.1.1.2:8081;
check interval=3000 rise=2 fall=5 timeout=2000 type=http;
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx http_4xx;
}
upstream portalBackendGray {
server 10.1.1.3:8081;
check interval=3000 rise=2 fall=5 timeout=2000 type=http;
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx http_4xx;
}
location ~/api/(.*) {
#...............error.log......notice
rewrite_log on;
#...............account_is_include(userAccount, check_userAccount)
#rewrite ^/api/(.*)$ /$1 break;
set_by_lua_block $my_ups {
function account_is_include(value, tab)
local table = json.decode(tab)
for k,v in ipairs(table) do
if string.lower(v) == string.lower(value) then
return true
end
end
return false
end
local headers = ngx.req.get_headers()
local userAccount = headers["grayAccount"]
if userAccount == nil then
return "portalBackend"
end
check_userAccount = ngx.shared.portalCache:get("userAccountList")
if check_userAccount ~= nil and account_is_include(userAccount, check_userAccount) then
local key = ngx.shared.portalCache:get("switchKey")
if key == "gray" then
return "portalBackendGray"
else
return "portalBackend"
end
else
return "portalBackend"
end
}
proxy_pass http://$my_ups/$1$is_args$args;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#websocket
proxy_set_header Origin '';
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
最后,介绍一下灰度发布的流程图:
?
|