基於nginx redis 前端灰度

2021-10-24 14:23:52 字數 4684 閱讀 2753

專案採用的是前後端分離,前端使用vue 後端使用spring cloud。單點採用cas。本文暫且討論前端基於cookie-token的灰度。

nginx:根據cookie分流,灰度發布基於使用者才更合理(本例子採用該種方式)。

1.首先使用者經過cas登入後訪問vue前端資源會攜帶access_token。

2.在lua指令碼連線redis伺服器,驗證token是否在灰度列表和清單中。

3.token灰度驗證通過,交由nginx伺服器進行反向**服務到灰度伺服器;

安裝瀏覽器cookie外掛程式 editthiscookie

nginx lua 環境安裝

--引入nginx-redis模組

local redis=require "resty.redis";

--初始化redis客戶端

local red=redis:new();

--設定超時時間1000ms

red:set_timeout(1000);

--redis建立連線

local ok,err=red:connect("39.100.254.100", 6379);

--如果建立連線失敗,則請求正常服務

if not ok then

ngx.say("failed to connect redis ",err);

return;

end-- 請注意這裡 auth 的呼叫過程 這是redis設定密碼的

local count

count, err = red:get_reused_times()

if 0 == count then

--密碼

ok, err = red:auth("2019")

if not ok then

ngx.say(cjson.encode())

return

endelseif err then

ngx.say("failed to get reused times: ", err, "

") return

end--選擇的桶

red:select(8)

--獲取請求ip

local local_ip = ngx.req.get_headers()["x-real-ip"];

if local_ip == nil then

local_ip = ngx.req.get_headers()["x_forwarded_for"];

endif local_ip == nil then

local_ip = ngx.var.remote_addr;

endlocal_ip=ngx.var.remote_addr;

--redis中獲取白名單

local ip_lists=red:get("gray");

--ngx.say("ip_list" .. ip_lists);

--判斷是否在白名單然後轉到對應服務

if string.find(ip_lists,local_ip) == nil then

--一定要注意,當這裡ngx.exec()的時候,前面一定不能用任何的輸出

ngx.exec("@prod1");

--ngx.say("prod1");

else

--一定要注意,當這裡ngx.exec()的時候,前面一定不能用任何的輸出

ngx.exec("@prod2");

--ngx.say("prod2");

endlocal ok,err=red:close();

啟動

/usr/local/openresty/nginx/sbin/nginx -c /usr/local/openresty/gray/conf/nginx.conf
停止

/usr/local/openresty/nginx/sbin/nginx -c /usr/local/openresty/gray/conf/nginx.conf -s stop
指令碼還在根據實際專案調整中,還未更加cookie中的access_token 來進行灰度。

local cjson = require("cjson")

local redis=require "resty.redis";

local red=redis:new();

--ngx.log(ngx.info, " msg:", "helloworld")

red:set_timeout(1000);

--redis連線

local ok,err=red:connect("39.100.254.140", 6379);

if not ok then

ngx.say("failed to connect redis ",err);

return;

end-- 請注意這裡 auth 的呼叫過程 這是redis設定密碼的

local count

count, err = red:get_reused_times()

if 0 == count then

ok, err = red:auth("portal2019")

if not ok then

ngx.say(cjson.encode())

return

endelseif err then

ngx.say("failed to get reused times: ", err, "

") return

end--密碼和選擇的桶

red:select(8)

--accesstoken

function get_cookie(s_cookie, key)

local value = nil

-- string.gfind is renamed to string.gmatch

for item in string.gmatch(s_cookie, "[^;]+") do

local _, _, k, v = string.find(item, "^%s*(%s+)%s*=%s*(%s+)%s*")

if k ~= nil and v~= nil and key ==k then

return v

endend

return value

endlocal isnull = function(v)

return not v or v == ngx.null

endlocal raw_cookie = ngx.req.get_headers()["cookie"]

local accesstoken = get_cookie(raw_cookie, "accesstoken");

--ngx.say("accesstoken :" .. accesstoken)

-- 當accesstoken不存在時候預設路由

if accesstoken == nil then

--ngx.say("prod1");

ngx.exec("@prod1");

local ok,err=red:close();

return;

end--redis中獲取白名單

local rdsaccesstoken=red:get("gray:token:" .. accesstoken);

--ngx.say("rdsaccesstoken:", cjson.encode(rdsaccesstoken));

--判斷是否在白名單然後轉到對應服務

if isnull(rdsaccesstoken) then

--一定要注意,當這裡ngx.exec()的時候,前面一定不能用任何的輸出

ngx.exec("@prod1");

--ngx.say("prod1");

else

--一定要注意,當這裡ngx.exec()的時候,前面一定不能用任何的輸出

ngx.exec("@prod2");

--ngx.say("prod2");

endlocal ok,err=red:close();

前端請求封裝(基於 axios ts)

處理統一邏輯,包括 異常捕獲 資料上報 狀態碼處理 請求快取 csrf 處理 跨域處理 token 生命週期管理等 抽象這一層後,可以做到隨意更換請求庫 axios fetch 甚至 xhr 但是對外用法不變 提供快取能力,當傳參不變時,可選擇快取結果,用mem實現,config.cacheable...

基於react的前端專案結構

build 編譯目錄 config webpack配置 public 公共檔案 可以放一些第三方字型 樣式庫等 scripts 啟動指令碼 src asset 靜態資源 components 公共元件目錄 當業務需要拆分元件的時候,可以在對應的業務資料夾下單獨建立乙個components資料夾 mo...

前端基於jquery的UI框架

正在做的乙個專案選擇jquery作為前端js核心庫。然後就想選乙個基於jquery的ui庫,然後悲催的事情發生了。至於為什麼使用jquery,一是因為不想為授權費用,而又不想引起可能法律糾紛 另一方面jquery也是所有最容易上手和流行的js庫。如果ext要用於商用就要付版權費,這個不行 dojo的...