1. 程式人生 > 實用技巧 >Openresty+Lua+Redis灰度釋出

Openresty+Lua+Redis灰度釋出

轉載https://www.cnblogs.com/Eivll0m/p/6774622.html

灰度釋出,簡單來說,就是根據各種條件,讓一部分使用者使用舊版本,另一部分使用者使用新版本。百度百科中解釋:灰度釋出是指在黑與白之間,能夠平滑過渡的一種釋出方式。AB test就是一種灰度釋出方式,讓一部分使用者繼續用A,一部分使用者開始用B,如果使用者對B沒有什麼反對意見,那麼逐步擴大範圍,把所有使用者都遷移到B上面 來。灰度釋出可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度。上述描述的灰度方案A和B需要等量的伺服器,這裡我們所做的灰度釋出稍作改變:用1-2臺機器作為B,B測試成功再部署A。用於WEB系統新程式碼的測試釋出,讓一部分(IP)使用者訪問新版本,一部分使用者仍然訪問正常版本,原理如圖:

執行過程:
1、當用戶請求到達前端web(代理)伺服器Openresty,內嵌的lua模組解析Nginx配置檔案中的lua指令碼程式碼;
2、Lua獲取客戶端IP地址,去查詢Redis中是否有該鍵值,如果有返回值執行@clien2,否則執行@client1。
3、Location @client2把請求轉發給預釋出伺服器,location @client1把請求轉發給生產伺服器,伺服器返回結果,整個過程完成。

Openresty部分配置如下:

upstream client1 { 
        server 127.0.0.1:8080;  #模擬生產伺服器
    }
upstream client2 {
        server 127.0.0.1:8090;  #模擬預釋出伺服器
    }

server {
        listen       80;
        server_name  localhost;
        
        location ^~ /test {
            content_by_lua_file /app/ngx_openresty/nginx/conf/huidu.lua
        }
        
        location @client1{
                proxy_pass http://client1;
        }
        location @client2{
                proxy_pass http://client2;
        }
     }

Lua指令碼內容如下:

local redis = require "resty.redis" 
local cache = redis.new() 
cache:set_timeout(60000)

local ok, err = cache.connect(cache, '127.0.0.1', 6379) 
if not ok then 
    ngx.say("failed to connect:", err) 
    return 
end 

local red, err = cache:auth("foobared")
if not red then
    ngx.say("failed to authenticate: ", err)
    return
end

local local_ip = ngx.req.get_headers()["X-Real-IP"]
if local_ip == nil then
    local_ip = ngx.req.get_headers()["x_forwarded_for"]
end

if local_ip == nil then
    local_ip = ngx.var.remote_addr
end
--ngx.say("local_ip is : ", local_ip)

local intercept = cache:get(local_ip) 


if intercept == local_ip then
    ngx.exec("@client2")
    return
end

ngx.exec("@client1")

local ok, err = cache:close() 
 
if not ok then 
    ngx.say("failed to close:", err) 
    return 
end

驗證:
url:http://192.168.116.145/test/n.jpg (模擬生產環境)
客戶端IP:192.168.116.1(模擬公司辦公網IP)

1、訪問http://192.168.116.145/test/n.jpg
返回的結果是生產伺服器的。

在Redis存入客戶端IP:

繼續訪問:
請求到的是預釋出伺服器返回的結果。

在Redis中刪除客戶端IP:

然後重新整理瀏覽器:
返回生產伺服器的結果。

分類:Web server