Openresty+Lua+Redis灰度釋出
阿新 • • 發佈:2020-11-20
轉載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:
然後重新整理瀏覽器:
返回生產伺服器的結果。