一、背景

1.1 需求

为了降低代码上线的故障率,通过生产环境的openresty实现流量的控制,对新版本的代码进行一次灰度验证(新版本在灰度环境,连接生产数据库等组件,供内部人员测试)。这里通过浏览器等客户端携带特有标头,将流量转发至灰度环境。

1.2 架构实现

lua-nginx-module模块参考地址:https://github.com/openresty/lua-nginx-module

image-20250329110608045

备注:这里我从balancer_by_lua这个hook钩子函数处进行代码拦截。适用于将请求转发至下游系统时的场景(当nginx作为反向代理时都符合)

二、代码配置

2.1 lua代码
root@VM-12-8-ubuntu:/usr/local/openresty/nginx/conf# pwd
/usr/local/openresty/nginx/conf
root@VM-12-8-ubuntu:/usr/local/openresty/nginx/conf# mkdir lua    # 创建lua代码的目录
root@VM-12-8-ubuntu:/usr/local/openresty/nginx/conf/lua# cat streambalancer.lua 
local _M = { _VERSION = '0.1' }

function _M.headercheck()
    local gray = ngx.req.get_headers()["gray"]
    local beta = ngx.req.get_headers()["beta"]
    if gray then
        return "gray"
    elseif beta then
        return "beta"
    else
        return "prod"
    end
end

function _M.setbalancer(hostIp,serverPort)
    local balancer = require('ngx.balancer')
    local host = hostIp
    local port = serverPort
    local ok,err = balancer.set_current_peer(host, port)
    if not ok then
        ngx.log(ngx.ERR, "failed to set the current peer: ", err)
        return ngx.exit(500)
    end

end

return _M
2.2 代码解释

headercheck函数用来获取到对应标头,并且返回一个字符串。setbalancer函数用来设置upstream的转发请求至下游服务的ip和端口(由于gray、beta都是内部验证的环境,不需要考虑高可用)。

三、nginx配置

3.1 配置nginx加载lua模块
root@VM-12-8-ubuntu:/usr/local/openresty/nginx/conf# vim nginx.conf        # 在http模块下添加如下代码
  lua_package_path "/usr/local/openresty/nginx/conf/waf/?.lua;/usr/local/openresty/nginx/conf/lua/?.lua;;";

img

3.2 配置upstream
root@VM-12-8-ubuntu:/usr/local/openresty/nginx/conf/vhost# vim upstream.conf
upstream bytebase_web {
    server 127.0.0.1:8001 weight=100;

    balancer_by_lua_block {
      local streambalancer = require("streambalancer")
      local ret = streambalancer.headercheck()
      if ret == "gray" then
          streambalancer.setbalancer("127.0.0.1","8000")
      elseif ret == "beta" then
          streambalancer.setbalancer("172.20.8.239","32450")
      end
    }
}

img

3.3 配置解释

通过获取相应标头,判断返回值为”gray”或”beta”后转发至对应的环境。

四、客户端配置举例

配置对应的header标头。移动端需要在请求时携带对应标头,原理是一样的。

image-20250329111049179

https://modheader.com/

五、总结

1;这种模式一般是在反向代理入口处进行配置,比如nginx–>web-frontend,或者nginx–>gateway-api等。

2;在k8s集群中配置一套生产环境,一套灰度环境。常见名称空间命名方式为: 生产环境:project-g6p-prod,灰度环境:project-g6p-gray。

最后修改日期: 2025年3月29日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。