如何利用Nginx為系統構筑發布前的最后一道防線
背景
在項目發展的早期,為了簡單方便,我們升級服務器端應用,一般會先將應用源碼或程序包上傳到服務器,然后再停掉老版本服務,啟動新版本服務。由于此時,項目用戶少訪問量小,這樣做通常不會有什么太大問題。但后面隨著項目越來越大,用戶越來越多,再這樣做你會發現存在兩個明顯的問題。
1、在新版本升級過程中,服務是暫時中斷的,在這期間,服務將不可使用。
2、如果新版本有BUG,升級失敗,回滾起來將非常麻煩,容易造成更長時間的服務不可用。
為了解決上面這些問題,人們研究出了很多發布策略,如藍綠發布、滾動發布等,下面要講的灰度發布也是其中之一。
什么是灰度發布
灰度發布也叫金絲雀發布,其原理如下圖所示:
用文字描述即在灰度發布開始后,我們會先啟動一個新版本應用V2,但是此時并不直接將流量切過來,而是先讓測試人員對新版本進行線上測試。如果測試沒有問題,那么就將少量的(如圖中的5%)用戶流量導入到新版本上,然后再對新版本做運行狀態觀察,收集各種運行時數據。當確認新版本運行良好后,再逐步將更多的流量導入到新版本上。
在此期間,我們可以不斷地調整新舊兩個版本的運行的服務器副本數量,以使得新版本能夠承受越來越大的流量壓力。當最后我們將100%的流量都切換到新版本上后,就可以關閉剩下的老版本服務,完成灰度發布。
另外,如果在灰度發布過程中發現新版本有問題,我們可以立即將流量切回老版本上,這樣,可以將負面影響控制在最小范圍內。
如何實現灰度發布
實現灰度發布有多種方式,但總結起來有三類
- 基于IP
- 基于COOKIE
- 基于權重
如下是利用nginx對這三類的實現。
1、基于IP
我們利用LUA,先獲取客戶端IP,然后通過判斷客戶端IP的類型,來判斷應該選擇訪問什么服務器。如果是客戶端IP為公司出口IP,則反向代理到@client;如果不是,則反向代理到@client_test。如下:
2、基于Cookie
我們先定義三個upstream,tts_v6、tts_v7和default,然后查詢Cookie鍵為version的值,如果該Cookie值為tts1,則轉發到tts_v6;如果該Cookie值為tts2,則轉發到tts_v7;如果該Cookie值既不是tts1,也不是tts2,則默認走default所對應的服務器。如下:
其中,192.168.3.81:5380所指向的服務器為運行新功能的服務器。
3、基于權重
我們定義一個upstream,設置三個服務器IP,其權重分別為5,3,1。我們先把新功能部署在權重為1的服務器上,然后使用ip_hash進行負載均衡。待權重為1的服務器運行沒有問題后,就將新功能部署到權重為3的服務器。如此重復操作,最后將新功能部署到所有服務器上。如下:
總結
灰度發布雖然操作復雜,但在一定程度上保證了系統的安全與穩定。隨著項目的不斷發展,系統穩定越來越比完善功能更加重要。從長遠來看,使用灰度發布利大于弊。