栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

OpenResty实现按租户灰度发布

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

OpenResty实现按租户灰度发布

K8s上的一套SaaS服务,每个租户都有自己的独立数据库,前后端分离,后端微服务,前端Nginx。

当SaaS服务升级的时候,需要按照租户逐个进行升级,因此升级过程中需要逐步将租户迁移到新的服务上,后端基于 Spring Cloud Gateway 实现,前端通过 OpenResty 结合 K8s Service 实现。

OpenResty 配置代码

基础代码如下:

worker_processes  1;
error_log logs/error.log debug;
events {
    worker_connections 1024;
}

http {

    # 确定要请求哪个HTTP服务
    access_by_lua_block {
        -- 使用 redis 获取租户信息,为了lua代码高亮,代码放在后面单独块中
    }

    # 通过负载均衡方式选择后端服务
    upstream backend {
        server nginx-ui-service:80;   # 默认前端服务,使用 K8s Service

        balancer_by_lua_block {
            -- 根据租户信息进行负载均衡,为了lua代码高亮,代码放在后面单独块中
        }

        keepalive 10;  # connection pool
    }

    server {
        # this is the real entry point
        listen 80;

        location / {
            # make use of the upstream named "backend" defined above:
            proxy_pass http://backend;
        }
    }

}

这里主要用到了两个指令 access_by_lua_block 和 balancer_by_lua_block,在前一个指令中获取租户信息,在第二个中根据获取的信息执行负载均衡。

access_by_lua_block 大括号中的代码:

-- 请求头: ngx.header.tenant
-- 示例从 url 参数获取租户信息
local arg = ngx.req.get_uri_args()
if nil == arg.tenant then
    return
end

local redis = require "resty.redis"

local red = redis:new()
red:set_timeouts(1000, 1000, 1000)

-- K8s Service: redis-server
local ok, err = red:connect("redis-server", 6379)
if not ok then
    ngx.say("failed to connect: ", err)
    return
end
-- 获取 host
local res, err = red:get("tenant:"..arg.tenant..":host")
if res ~= ngx.null then
    ngx.ctx.tenant_host = res
else
    ngx.log(ngx.INFO, "tenant: " .. arg.tenant .. " 没有配置")
end
-- 获取端口
res, err = red:get("tenant:"..arg.tenant..":port")
if res ~= ngx.null then
    ngx.ctx.tenant_port = res
else
    -- 默认值 80
    ngx.ctx.tenant_port = 80
end

ok, err = red:set_keepalive(10000, 100)
if not ok then
    ngx.say("failed to set keepalive: ", err)
    return
end

从redis读取租户信息,如果不存在后续会用默认路由,如果有就存到 ngx.ctx 中。

balancer_by_lua_block 中的内容:

local balancer = require "ngx.balancer"

if nil ~= ngx.ctx.tenant_host then
    local ok, err = balancer.set_current_peer(ngx.ctx.tenant_host, ngx.ctx.tenant_port)
    if not ok then
        ngx.log(ngx.ERR, "failed to set the current peer: ", err)
        return ngx.exit(500)
    end
end

读取 ngx.ctx 中的租户信息,然后设置负载均衡的地址。

灰度流程
    当前 nginx-ui-service Service 选择的 V1 版本的前端服务。启动 V2 版本的前端服务。当租户的前后端都升级为最新版本后,在 redis 设置租户 tenant:1:host 要选择的服务版本 V2当所有租户都升级到V2后,切换 nginx-ui-service Service 选择的 V2 版本的前端服务。清除所有租户 redis 中的服务版本信息。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/785828.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号