实现AB发布的方案
核心基于openresty实现根据用户登陆后的tag 确定用户的标签对应的页面
注意:
- 接口层面需要保证有版本控制
- 数据库的修改只加字段不减字段
- 需要有统一的域名保存nginx 可以登陆页面的写入的cookie
- jenkins上配置两个项目 全量 和 AB
初级版本
初级版本 A B对应的页面写死,用户只有AB两个状态
服务器上部署两个页面文件夹
关键配置
从header中获取token
local headers = ngx.req.get_headers()
local token = headers["token"]
从cookie中获取token
token = ngx.var.cookie_token
-- 获取key对应的tag 值
local tag = red:hget(key,"tag");
-- 根据tag 去往对应的页面
if tag == "A" then
ngx.var.pagePath = "webA"
else
ngx.var.pagePath = "webB"
end
修改session tag
再次刷新
lua脚本
-- 实现AB选择的lua脚本 初级版本
-- 注意 pagePath 在外部定义 set $pagePath webA;
-- 第一步 获取请求中的token ,token来源与header或者cookie
local doAB = true
local headers = ngx.req.get_headers()
local token = headers["token"]
-- 如果请求头中没有token 就从cookie中找
if token == nil then
token = ngx.var.cookie_token
end
if token == nil then
doAB = false;
end
-- ngx.log(ngx.ERR,"@@@@@get token: " .. token)
-- 存在token信息才做AB选择
if doAB then
local dec = ngx.decode_base64(token)
local sindex = string.find(dec,",",1);
-- 获取redis中用户信息key
local key = "us:WEB:" .. string.sub(dec,1,sindex-1)
ngx.log(ngx.ERR,"@@@@@session key: " .. key)
-- 需要明确的指定引入redis
local redis = require "resty.redis";
-- 如果使用连接池的话,每次new的时候,他其实是从全局队列里获取可用的连接.
red = redis:new();
-- 设置超时时间
red:set_timeout(1000)
-- 连接redis 模板式的写法
local ok, err = red:connect("192.168.0.206", 6379);
if not ok then
-- 无法连接就自己退出
return
end
-- 通过 redis_conn:get_reused_times() 方法获取 该连接被使用的次数。
-- 如果为0才做选择数据库 设置密码等工作,可以减少网络IO
if red:get_reused_times() == 0 then
-- 输入密码
red:auth("xxxxx");
-- 可以切换数据库
ok, err = red:select(2)
if not ok then
-- ngx.say("failed to select db: ", err)
return
end
end
-- 获取key对应的tag 值
local tag = red:hget(key,"tag");
if tag == ngx.null or tag == nil then
return
end
ngx.log(ngx.ERR,"@@@@@user tag: " .. tag)
local ok, err = red:set_keepalive(10000, 10) --
if not ok then
return
end
-- 根据tag 去往对应的页面
if tag == "A" then
ngx.var.pagePath = "webA"
else
ngx.var.pagePath = "webB"
end
end
nginx配置
server {
listen 80;
# 需要和登陆页面在同一个域名下
server_name ab.medcrab.com;
location / {
default_type text/html;
charset utf-8;
# 默认进入A页面
set $pagePath webA;
access_by_lua_file /xx/xx/xx/xx/ab-choose1.lua;
root /medcrab/web/task-server/$pagePath;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}