OpenResty实现按租户灰度发布
Posted isea533
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 中的服务版本信息。
以上是关于OpenResty实现按租户灰度发布的主要内容,如果未能解决你的问题,请参考以下文章