場景
當版本切換的時候,後端服務器不可能瞬間同時進行代碼更新,這樣就會出現客戶在短暫時間內訪問到不同版本的服務。
使用以下流程可以避免上述問題:
1.後端設立兩個的主機組(A_CLUSTER,B_CLUSTER),以及一個ALL_CLUSTER包含兩個主機組提供服務。
2.當要發佈前,將所有的流量切換到B_CLUSTER。
3.切換完畢後升級A_CLUSTER代碼。
4.將流量再切換到A_CLUSTER。
5.再升級B_CLUSTER的代碼。
6.最後將流量再切換至兩CLUSTER。
要完成上述操作,在代碼更新方面有jenkins等發佈工具來實現。但前端切換流量的在傳統中只能通過手動修改nginx配置文件來實現。
openresty提供了一個可編程的nginx,通過lua可以實現對於nginx的”在線修改”,從redis獲取信息從而選擇將請求發送到後端指定的upsteam。而如何指定所需要的upstream?這時就需要redis,或者其他的中間件或其他lua可以調用的接口來實現。
準備工作
1.安裝redis
2.安裝openrestry
3.安裝lua
4,安裝lua的redis驅動
配置分享
nginx.conf:
http {
lua_shared_dict vtimes 10m;
upstream a_cluster {
server 192.168.1.200:8888;
}
upstream b_cluster {
server 192.168.1.203:8080;
}
init_by_lua_block {
cache = ngx.shared.vtimes
cache:set("times",1000)
redis = require "redis"
client = redis.connect('127.0.0.1', 6379)
local cluster = client:get("usCluster");
cache:set("cluster",cluster);
}
server {
listen 8080;
location ~ /vtimes/ {
content_by_lua_block{
cache = ngx.shared.vtimes;
times = cache:get("times");
ngx.say(times);
}
}
location / {
set_by_lua_block $upstream{
cache = ngx.shared.vtimes;
vtimes = cache:get("times");
if(vtimes > 0)then
cluster = cache:get("cluster");
vtimes = vtimes - 1;
cache:set("times",vtimes);
return cluster;
else
redis = require "redis"
client = redis.connect('127.0.0.1', 6379)
local cluster = client:get("usCluster");
cache:set("times",1000);
cache:set("cluster",cluster)
return cluster;
end
}
proxy_pass http://$upstream;
}
}
配置說明
1.如果每次訪問都需要訪問redis,這將導致效率下降。
2.基於第一條原因,我們設定這樣一個機制,每1000次(這個數值可以自己設定),從redis中獲取指定的upstream數值,然後保存在內存中,並使用這個設定。
3.這樣除了需要在redis中保存數據,還需要在openrestry中保存當前upstream以及訪問次數的數據。
4.lua_shared_dict vtimes 10m;開闢了一個共享內存空間,可以將數據以key-value形式保存到內存內。
5.建立兩個upstream,這裏作爲演示就做的比較簡單,事實上可以做無數多個,用於指定。
6.init_by_lua_block;用於初始化數據,在程序啓動前,就從redis中獲取設定的訪問upstream,以及設定訪問次數。
7./vtimes/;用於查看訪問次數,當次數到達0之後,openresty將重新獲取配置。當然也可以配置一個用於清零這個計數器的接口。
8.set_by_lua_block $upstream 這裏通過lua腳本給變量upstream賦值(計算的方法上文中已經明確說明過),並將這個值作爲proxy_pass的參數,實現自動切換。
9.控制流量切換的是redis中的key:usCluster,將它設定爲a_cluster或者b_cluster就能實現流量切換。在自己的運維平臺上層再實現業務邏輯提供了很大的便利和可能。完善在線發佈的流程。