基於 Nginx 實現灰度發佈與 AB 測試

背景

單位的雲辦公相關係統沒有成熟的平滑發佈方案,導致每一次發佈都是直接發佈,dll 文件或配置文件的變更會引起站點的重啓。 

雲辦公系統的常駐用戶有 10000+,即使短短半分多鐘,也會收到一堆投訴。基於此,我們梳理了一套平滑發佈的方案。

實施方案

1、跟 nginx 代理服務器約定了一個健康檢查的接口

2、通過接口返回的 http 狀態碼來讓 ngx 是否分流用戶請求(這個我們單位的技術部那邊有標準的做法)

3、根據提供的這個服務健康檢查的接口:nginx 判斷只要某個實例的接口返回 5xx 的狀態碼,即把該實例下線(nginx 不會把流量轉發到該實例)

發佈流程

目的主要是爲了發佈的時候能夠平滑發佈,所以 QA 與開發人員在發佈得時候按照如下步驟操作:

1、打開系統的 nginx 列表管理頁面:[/publish/ngxconfig]

2、下架某一個實例(假設系統集羣有 A、B、C 個實例),比如 A 實例

3、查看是否下架成功:這個就是我們跟 nginx 約定的健康檢查接口,正常在線狀態下是 200 的 statu,切離線後,這個接口返回的是 401 的 statu。

在線情況:

離線情況:

4、觀察監控站點,直至該實例下的 Req、Connnectiuon 流量都消失

 

5、在該實例下進行版本發佈

6、打開 Fidller,host 到待發布的實例,然後判斷是否發佈成功(發佈 dll、配置文件時,IIS 站點會短暫重啓)

7、QA 同學走查灰度的 A 實例服務器,保證它正常運行,如此循環,直到所有服務器都發布。

**進一步 AB 測試的優化 **

平滑發佈做完之後,確實給我帶來很大的便利,不用每次發佈都發公告,不重要的或者非功能性的內容發佈了就是了。

但是用久了,客戶量上去之後,又遇到一個問題,那就是每一次業務大變更,大型發佈都是直接發佈到生產,這樣可能存在風險。設計師設計的功能,用戶不一定完全接受,一旦上線新版本,收到一大堆的吐槽,都是用戶呀,如果能在小範圍人羣內進行灰度試用,完成平穩的過度和使用反饋之後,優化後再上到生產會更好一點。

所以這邊需要思考和設計一套統一的技術方案,未來無論雲辦公還是其他的業務系統,都能通過灰度發佈在可指定的小範圍內先進行體驗和功能驗證。

基於上面的平滑,我們在 Nginx 反向代理服務器上動心思,讓 nginx 來幫我們做 ABTesting 的方案。

以下是我們嘗試的幾種方案:

**1、Nginx 反向代理:來路 IP 策略 **

流程圖:

步驟:

1、進入雲辦公系統,進入 Nginx 反代服務器

2、Nginx 讀取來路 IP 的 AB 名單

3、根據 IP AB 名單進行流量轉發 (名單 A 走特定實例,名單 B 走雲辦公原有集羣實例)

server {
listen 80;
server_name officecloud.com;
access_log officecloud.com/logs main;
ip_list 192.168.254.4,192.168.254.170
set $group default;
if ($remote_addr in iplist) {
set $group ACluster;
}
location / { 
proxy_pass http://$group;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.htm;
}
}

優缺點:

1、配置簡單,原資源平臺的灰度升級就是根據 IP 名單來劃分設計升級的

2、外部計算機很多都是非固定 IP,這個適合在公司內網實現,比如只是配置公司內網的 IP。

**2、Nginx 反向代理:$.Cookies 策略 **

流程圖:

步驟

1、進入雲辦公系統,進入 Nginx 反代服務器

2、Nginx 讀取 Http 請求的 Cokie 的 version 信息(也可以是別的 key)

3、根據 Key 的版本來進行流量轉發 (比如 Version1.1 走特定集羣,Version1.0 走通用集羣實例) 

server {
listen 80;
server_name officecloud.com;
access_log officecloud.com/logs main;
ip_list 192.168.254.4,192.168.254.170
set $group default;
if ($http_cookie ~* "version=V1.0"){
set default;
}
if ($http_cookie ~* "version=V1.1"){
set $group ACluster;
}
location / { 
proxy_pass http://$group;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.htm;
}
}

優缺點:

1、配置簡單,根據 Nginx 的 $COOKIE_version 屬性來判斷

2、相對穩定,對需要開放名單的用戶,在 Cookie 頭部加入特定的版本即可,應用只要少許的開發量

3、首次訪問靜態頁面可能不會產生 cookie

備註:這是團隊內認爲最好的 Nginx 代理方案,同理,User-Agent 和 Header 都可以做此種類型的判斷,但是 Header 需要侵入底層 HttpRequest 去業務添加,不建議。

**3、AB 集羣 + 業務代理方式 **

流程圖:

步驟:

1、進入雲辦公系統,兩種方式進入系統,一種是登錄頁登錄:~/login ,一種是 default 頁面帶 uckey 登錄:~/default?usertoken=#usertoken#

2、登錄的時候和 usertoken 傳入的時候進去 路由代理模塊, 進行用戶信息校驗,根據不同的人員和部門 (人員和部門配置歸屬 AB 名單) 分流到兩個不同的 AB 集羣

3、根據轉發跳到具體的實例集羣域名下(可以配置 AB 集羣擁有不同域名, 更容易區分)

優缺點 :

1、與 Nginx 剝離,不用依賴公司的通用平臺和技術部的實現

2、需要申請 AB 集羣,AB 集羣擁有不同的域名。

3、如果是前後端分離情況下,需要保證靜態站點和服務站點均申請 AB 集羣

4、所有入口需要統一做代理,有一定的開發量

目前手上 2 個系統已經根據該方案實現了。

來自:https://www.cnblogs.com/wzh2010/
作者:翁智華

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/WBAkiaJ7WI7OMBDCVP3btg