0. 前言
之前的文章谈了蓝绿部署、灰度发布,今天让我们来动手实践一下。我们提前准备好两个WEB服务如下:
1. 无感知发布
这里我们使用Nginx的负载均衡来实现用户无感知发布,主要就是我们提供两台服务,当需要发布的时候一台一台的进行滚动升级,利用Nginx的负载均衡特性来实现用户无感知。
Nginx配置片段如下
upstream bobbytest {
server 192.168.1.108:9081;
server 192.168.1.108:9082;
}
server {
listen 8888;
location / {
proxy_pass $scheme://bobbytest;
}
}
该配置只是简单的测试使用,使用到生产环境时,根据自己的情况进行配置。
2. 使用OpenResty实现灰度发布
2.1. OpenResty简介
OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
OpenResty通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。
2.2. OpenResty安装
可以根据自己的需求参照官方文档进行安装 http://openresty.org/cn/installation.html
2.3. 原理说明
- 用户的Token对应的用户ID,灰度用户ID列表存放在Redis中
- 使用OpenResty提供的一些Nginx模块来进行判断请求用户具体引流到哪台服务
2.4. Nginx的server配置
server {
listen 9999;
location / {
default_type text/html;
# 执行指定的lua文件
content_by_lua_file /root/bobbytest/lua/test.lua;
}
# 主服务
location @MainServer {
proxy_pass http://127.0.0.1:9081;
}
# 灰度服务
location @GrayscaleServer {
proxy_pass http://127.0.0.1:9082;
}
}
2.5. 灰度lua文件
-- 链接Redis
local redis = require "resty.redis"
local red = redis:new()
local ok, err = red:connect("192.168.1.105", 6379)
if not ok then
ngx.say("failed to connect: ", err)
return
end
-- 获取用户token
local token = ngx.req.get_headers()["Authorization"]
if token ~= nil then
-- 通过token获取用户id
local userId = red:get(token)
-- 判断是否是灰度范围用户
local isGrayscale, err = red:smismember("GRAYSCALE_USER_IDS", userId)
if isGrayscale[1] == 1 then
-- 符合灰度条件的用户走灰度服务
ngx.exec("@GrayscaleServer")
return
end
end
-- 默认走主服务
ngx.exec("@MainServer")
2.6. 测试
Redis存放测试数据如下
测试数据如下
3. End
类似的实现用户无感知发布、灰度发布的方式还有很多。比如使用一些网关中间件,如Apache APISIX等,具体使用哪种方式,需要根据场景进行选择。
参考资料:
http://openresty.org/cn
https://github.com/openresty/lua-resty-redis