34.0金絲雀釋出、滾動釋出、藍綠髮布
金絲雀釋出、滾動釋出、藍綠髮布到底有什麼差別?關鍵點是什麼?
根據 2017 年的 DevOps 發展報告,高效能組織和低效能組織在軟體交付的效率上有數量級上的差異。技術組織的軟體交付能力是一種綜合能力,涉及眾多環節,其中釋出是尤為重要的環節。
作為技術人員,大家可能聽說過“滾動釋出”和“藍綠髮布”等術語,但是很多人並不清楚這些術語背後的原理。本文試圖總結當前主流的釋出策略,每個的優劣,適用性,讓開發人員特別是架構師對現代釋出技術有一個更為清晰全面的認識,讓大家能夠根據自己的企業上下文,對釋出策略做出正確的選型和實踐。
一、單伺服器組釋出
先解釋下單伺服器組的概念,早先我們機器資源比較緊張,不像現在雲端計算和虛擬化(包括容器技術)這麼發達,所以應用機器基本是預先靜態分配好的(一般由運維負責分配),原來應用 A 住在這 n 臺機器上,那麼下次升級釋出的應用 A 也住在這 n 臺機器上,所以稱為單伺服器組釋出方式。
1.1 蠻力釋出
如下圖所示,這種釋出方式比較簡單粗暴,有點像我們傳統的軟體升級方式,主要靠手工完成,先將老版本 V1 全部下掉,再將新版本發到機器上去。這種方式會引入服務中斷(停機),在開發測試環境是可行的,但對於生產環境釋出,其會直接影響使用者的使用體驗,這種方式一般是不建議的。
釋出前
釋出後
優勢和適用場合
優勢:
-
簡單成本低
不足:
-
服務中斷使用者受影響,出了問題回退也慢
適用場合:
-
開發測試環境
-
非關鍵應用(使用者影響面小)
-
初創公司什麼都缺,找夜深人靜使用者訪問量小的時間幹
流量模式
蠻力釋出會引入服務中斷時間,圖片來自附錄 6.1
1.2 金絲雀釋出(單伺服器組)
在蠻力釋出基礎上的一種簡單改進發布方式,目前仍然是不少成長型技術組織的主流釋出方式。單伺服器組下的金絲雀釋出的簡化步驟如下圖所示:
釋出前
先發一臺金絲雀
全部發完
實踐要點
-
金絲雀釋出一般先發 1 臺,或者一個小比例,例如 2% 的伺服器,主要做流量驗證用,也稱為金絲雀 (Canary) 測試(國內常稱灰度測試)。以前曠工開礦下礦洞前,先會放一隻金絲雀進去探是否有有毒氣體,看金絲雀能否活下來,金絲雀釋出由此得名。簡單的金絲雀測試一般通過手工測試驗證,複雜的金絲雀測試需要比較完善的監控基礎設施配合,通過監控指標反饋,觀察金絲雀的健康狀況,作為後續釋出或回退的依據。
-
如果金絲測試通過,則把剩餘的 V1 版本全部升級為 V2 版本。如果金絲雀測試失敗,則直接回退金絲雀,釋出失敗。
優勢和適用場合
優勢:
-
使用者體驗影響小,金絲雀釋出過程出現問題隻影響少量使用者
不足:
-
釋出自動化程度不夠,釋出期間可引發服務中斷
適用場合:
-
對新版本功能或效能缺乏足夠信心
-
使用者體驗要求較高的網站業務場景
-
缺乏足夠的自動化釋出工具研發能力
流量模式
少量金絲雀先接受流量,再全量釋出,圖片來自附錄 6.1
1.3 滾動式釋出(單伺服器組)
在金絲雀釋出基礎上的進一步優化改進,是一種自動化程度較高的釋出方式,使用者體驗比較平滑,是目前成熟型技術組織所採用的主流釋出方式。單伺服器組下的滾動釋出的簡化步驟如下圖所示:
釋出前
釋出中,先發一臺金絲雀
釋出中,再發若干臺
直到全部發完
實踐要點
-
滾動式釋出一般先發 1 臺,或者一個小比例,如 2% 伺服器,主要做流量驗證用,類似金絲雀 (Canary) 測試。
-
滾動式釋出需要比較複雜的釋出工具和智慧 LB,支援平滑的版本替換和流量拉入拉出。
-
每次釋出時,先將老版本 V1 流量從 LB 上摘除,然後清除老版本,發新版本 V2,再將 LB 流量接入新版本。這樣可以儘量保證使用者體驗不受影響。
-
一次滾動式釋出一般由若干個釋出批次組成,每批的數量一般是可以配置的(可以通過釋出模板定義)。例如第一批 1 臺(金絲雀),第二批 10%,第三批 50%,第四批 100%。每個批次之間留觀察間隔,通過手工驗證或監控反饋確保沒有問題再發下一批次,所以總體上滾動式釋出過程是比較緩慢的 (其中金絲雀的時間一般會比後續批次更長,比如金絲雀 10 分鐘,後續間隔 2 分鐘)。
-
回退是釋出的逆過程,將新版本流量從 LB 上摘除,清除新版本,發老版本,再將 LB 流量接入老版本。和釋出過程一樣,回退過程一般也比較慢的。
-
滾動式釋出國外術語通常叫 Rolling Update Deployment。
優勢和適用場合
優勢:
-
使用者體驗影響小,體驗較平滑
不足:
-
釋出和回退時間比較緩慢
-
釋出工具比較複雜,LB 需要平滑的流量摘除和拉入能力
適用場合:
-
使用者體驗不能中斷的網站業務場景
-
有一定的複雜釋出工具研發能力;
流量模式
滾動式釋出,流量平滑過渡,圖片來自附錄 6.1
二、雙伺服器組釋出
隨著雲端計算和虛擬化技術的成熟,特別是容器等輕量級虛擬化技術的引入,計算資源受限和申請緩慢問題已經逐步解決,可以做到彈性按需分配。為一次釋出分配兩組伺服器,一組執行現有的 V1 老版本,一組執行待上線的 V2 新版本,再通過 LB 切換流量方式完成釋出,這就是所謂的雙伺服器組釋出方式。
2.1 藍綠髮布(雙伺服器組)
藍綠髮布僅適用於雙伺服器組釋出,可以認為是對蠻力釋出的一種簡單優化釋出方式。簡化過程如下圖所示:
釋出前
釋出後
實踐要點
-
V1 版本稱為藍組,V2 版本稱為綠組,釋出時通過 LB 一次性將流量從藍組直接切換到綠組,不經過金絲雀和滾動釋出,藍綠髮布由此得名;
-
出現問題回退也很直接,通過 LB 直接將流量切回藍組。
-
釋出初步成功後,藍組機器一般不直接回收,而是留一個待觀察期,視具體情況觀察期的時間可長可短,觀察期過後確認釋出無問題,則可以回收藍組機器。
優勢和適用場合
優勢:
-
升級切換和回退速度非常快
不足:
-
切換是全量的,如果 V2 版本有問題,則對使用者體驗有直接影響;
-
需要兩倍機器資源;
適用場合:
-
對使用者體驗有一定容忍度的場景
-
機器資源有富餘或者可以按需分配(AWS 雲,或自建容器雲)
-
暫不具備複雜滾動釋出工具研發能力;
流量模式
藍綠髮布一次完成流程切換,圖片來自附錄 7.1
2.2 金絲雀釋出(雙伺服器組)
對藍綠部署的一種簡單優化,釋出時先從綠組拉入 1 臺金絲雀,待金絲雀驗證通過再發全量。對比藍綠髮布,該釋出方式的優勢是有一個生產流量的金絲雀驗證過程,可以減輕 V2 可能有問題的風險和影響面。簡化釋出過程如下圖所示:
釋出前
釋出中,先發一臺金絲雀
全量釋出
2.3 滾動式釋出(雙伺服器組)
滾動式釋出是對上面的藍綠和金絲雀釋出的進一步優化,按批次增量滾動釋出,提供更平滑的使用者體驗。
釋出前
釋出中,先發一臺金絲雀
釋出中,再發若干臺
直到全部發完
實踐要點
-
釋出前先申請一批新伺服器,數量一般和 V1 版本相同,將 V2 版本應用釋出到新伺服器上。例如如果在 AWS 雲上,則可以直接呼叫 API 申請一批新 VM,如果用容器雲 Kubernetes,則可以直接啟動一批新容器(使用 V2 版本容器映象)。
-
一般會先通過 LB 拉入 1 臺 V2 版本的機器,這臺機器也相當於金絲雀,用於流量驗證。
-
逐步按批次完成釋出,每批只需要通過 LB 拉入 V2 版本,再拉出對應數量的 V1 版本。批次之間留有觀察間隔,通過手工或監控反饋確保沒有問題再繼續釋出。
-
釋出有問題回退很快,直接通過 LB 將流量切回 V1 即可。
-
完成釋出後,一般 V1 版本要保留觀察以備萬一,比如留 1 天,1 天后沒有問題則回收 V1 機器資源。
優勢和適用場合
優勢:
-
使用者體驗影響小;
-
升級切換和回退(rollback)速度比單伺服器組滾動釋出要快,LB 切流量即可;
不足:
-
需要兩倍機器資源;
-
釋出工具比較複雜,LB 需要流量切換能力
適用場合:
-
使用者體驗不能中斷的網站業務場景
-
機器資源有富餘或者可以按需分配(AWS 雲,或自建容器雲)
-
有一定的釋出工具研發能力;
流量模式
滾動式釋出,流量平滑過渡,圖片來自附錄 6.1
三、其它釋出方式
上述都是偏傳統的釋出方式,能覆蓋大部分應用釋出場景。針對一些關鍵新功能的上線釋出,或者一些特定的場景,還有一些特殊的釋出方式。
3.1 功能開關釋出
利用程式碼中的功能開關(Feature Flag/Toggle/Switch)來控制釋出邏輯,一般不需要複雜的釋出工具和智慧 LB 配合,是一種相對比較低成本和簡單的釋出方式。這種方式也是支援現代 DevOps 理念,研發人員可以靈活定製和自助完成的釋出方式。功能開關的原理如下圖所示:
功能開關釋出,圖片來自附錄 6.2
實踐要點
-
功能開關釋出需要一個配置中心或者開關中心這樣的服務支援,例如攜程的 Apollo 配置中心附錄 6.3,或者開源的 FF4J附錄 6.4,這些都支援開關釋出,業界還有專門的功能開關 SaaS 服務,例如 LaunchDarkly附錄 6.5。通過配置中心,運維或研發人員可以在執行期動態配置功能開關的值。當然,功能開關釋出只是配置中心的一種使用場景,配置中心還能支援其它很多動態配置場景。
-
功能開關服務一般提供客戶端 SDK,方便開發人員整合。在執行期,客戶端 SDK 會同步最新的開關值,技術實現有推方式 (push),也有拉方式 (pull),或者推拉結合方式。
-
新功能(V2 new feature)和老功能(V1 old feature)住在同一套程式碼中,新功能隱藏在開關後面,如果開關沒有開啟,則走老程式碼邏輯,如果開關開啟,則走新程式碼邏輯。技術實現上可以理解為一個簡單的 if/else 邏輯。
-
應用上線後,開關先不開啟,然後運維或研發人員通過開關中心開啟新功能,經過流量驗證新功能沒有問題,則釋出完成;如果有問題,則隨時可以通過開關中心切回老功能邏輯。
優勢和適用場合
優勢:
-
升級切換和回退速度非常快
-
相對於複雜的釋出工具,實施比較簡單,成本相對低廉
-
研發能夠靈活定製釋出邏輯,支援 DevOps 自助釋出
不足:
-
切換是全量的,如果 V2 版本有問題,則對使用者體驗有直接影響;
-
對程式碼有侵入,程式碼邏輯會變複雜,需要定期清理老版本邏輯,維護成本變高
適用場合:
-
對使用者體驗有一定容忍度的場景
-
已有配置中心或開關中心服務
-
暫不具備研發複雜釋出工具能力;
流量模式
通過功能開關一次完成流量切換,圖片來自附錄 6.1
3.2 A/B 測試
A/B 測試附錄 7.10原來主要用於產品功能的比對測試,收集使用者反饋和對比資料做產品功能設計的決策。實際上,A/B 測試也可以作為一種新功能釋出技術。下圖展示基於 LB 實現的一種 A/B 測試釋出。
實踐要點
-
上圖中,原來 PC 端和手機端都訪問老版本 V1 服務(也稱 A 組或控制組),當 V2 新版本(也稱 B 組或實驗組)釋出以後,為了驗證 V2 的功能正確性,同時也為了避免 V2 有問題時影響所有使用者,先通過 LB 將手機端的流量切換到 V2 版本,經過一段時間的 A/B 比對測試和觀察(主要通過使用者和監控反饋),確保 V2 正常,則通過 LB 將全部流量切換到 V2。
-
基於 LB 方式實現 A/B 測試,LB 需要能夠通過某種條件做流量路由,例如通過 client ip,裝置型別,瀏覽器型別,甚至是定製的 HTTP Header 或查詢字串。
-
高階的 A/B 測試需要專門的平臺支撐,wasabi附錄 6.6就是 intuit 開源的一個支援高階 A/B 測試的平臺,這類平臺可以細粒度到針對某類使用者做 A/B 測試,例如針對某個地區的使用者,某個年齡段的使用者,公司內部使用者等等。舉了例子,假設一個關鍵業務的新功能上線,為了降低風險採用 A/B 測試,可以做到先只讓公司內部員工能訪問到新功能,待新功能驗證過,再全量放開給外部使用者使用。
-
功能開關和 A/B 測試有點相似,但功能開關一般是無狀態和全量的,無法做到針對某類特定使用者進行測試,而 A/B 測試一般是有狀態的,能夠跟蹤事務和使用者級別的狀態,可以實現針對某類特定使用者進行測試。
優勢和適用場合
優勢:
-
使用者體驗影響小;
-
可以使用生產流量測試;
-
可以做到針對某類特定目標使用者進行測試;
不足:
-
搭建複雜度相對高,有一定技術門檻
適用場合:
-
核心關鍵業務,比如涉及資金的
-
具備一定的 A/B 測試平臺研發能力
流量模式
針對某類目標使用者進行 A/B 測試,圖片來自附錄 6.1
3.3 影子測試
對於一些涉及核心業務的遺留系統的升級改造,為了確保萬無一失,有一種稱為影子測試的大招,採用比較複雜的流量複製、回放和比對技術實現。下面是影子測試的一個樣例架構圖,
實踐要點
-
目標實現老的 legacy 服務遷移升級到新的 experimental 服務。
-
測試開始前,需要在測試環境部署一份 legacy 服務和 experimental 服務,同時將生產資料庫複製兩份到測試環境。同時需要將生產請求日誌收集起來,一般可以通過 kafka 佇列收集,然後通過類似 goreplay附錄 6.8這樣的工具,消費 kafka 裡頭的請求日誌,複製回放,將請求分發到 legacy 服務和 experimental 服務,收到響應後進行比對,如果所有響應比對成功,則可以認為 legacy 服務和 experimental 服務在功能邏輯上是等價的;如果有響應比對失敗,則認為兩者在功能邏輯上不等價,需要修復 experimental 並重新進行影子測試,直到全部比對成功。根據系統複雜度和關鍵性不同,比對測試時間短的可能需要幾周,長的可達半年之久。
-
影子測試因為旁路在獨立測試環境中進行,可以對生產流量完全無影響。
-
影子測試一般適用於遺留系統的等價重構遷移,例如.net 轉 Java,或者 SQLServer 資料庫升級為 MySQL 資料庫,且外部依賴不能太多,否則需要開發很多 mock,測試部署成本會很高,且比對測試更加複雜和不穩定。
-
噹噹網有一個比較成功的交易系統.NET 轉 Java 遷移專案附錄 6.9,採用了影子測試技術,值得參考借鑑。
優勢和適用場合
優勢:
-
對生產使用者體驗完全無影響
-
可以使用生產真實流量進行測試(複製比對)
不足:
-
搭建複雜度很高,技術門檻高,資料庫的匯出複製是難點
-
外部依賴不能太多,否則測試部署成本很高,且比對測試更加複雜和不穩定
適用場合:
-
核心關鍵業務,比如涉及資金的
-
具備一定影子測試平臺研發能力,包括流量複製、資料庫匯出複製和分發比對系統。
流量模式
影子測試對生產流量無影響,圖片來自附錄 6.1
四、比較
下表對各種釋出策略,從各個維度進行綜合比較,供參考:
五、結論和建議
下面是對釋出策略的一些選型建議,供不同階段公司參考:
-
蠻力釋出一般是不建議採用的,除非是開發測試環境,使用者體驗不敏感的非關鍵應用,或者是創業期什麼都缺時候的無奈之舉。
-
如果暫時還不具備研發較複雜的滾動釋出工具和配套智慧 LB,則功能開關是一種不錯的輕量級釋出技術,投入相對較小的成本,可以讓研發人員靈活定製釋出邏輯。
-
金絲雀釋出通過少量新版本伺服器接收生產流量的方式去驗證新版本,可以顯著降低風險。金絲雀釋出適用於大部分場景,一般成長型公司就可以採用。
-
對於達到一定業務體量的公司,考慮到使用者體驗對業務的關鍵性,則需要投入研發資源開發支援滾動式釋出的工具和配套的智慧 LB,實現自動化和零停機的釋出。滾動式釋出一般和金絲雀釋出配合,先發一臺金絲雀去驗證流量,再按批次增量釋出。
-
隨著輕量級虛擬化(例如容器)的普及,雙伺服器組釋出方式具有更快的釋出和回退速度,是值得投入的高階釋出技術。藍綠部署僅適用於雙伺服器組,滾動式釋出既可以在單伺服器組上實現,也可以在雙伺服器組上實現。
-
對於涉及關鍵核心業務的新功能上線,採用 A/B 測試,可以顯著降低釋出風險,A/B 測試是唯一一種支援針對特定使用者組進行生產測試的高階釋出技術。當然 A/B 測試的投入不低,建議有一定研發能力的組織採用。
-
對於關鍵核心業務的遷移重構,為確保萬無一失,最後的一個大招是影子測試,影子測試對生產流量和使用者完全無影響。當然這個大招的投入成本和門檻都高,建議有足夠業務體量和研發能力的組織投入。
-
上述的各種釋出策略並不是非此即彼的,一個公司常常會綜合採用多種釋出技術作為互補,實現靈活的釋出能力。例如主流的釋出手段是金絲雀 + 滾動式釋出,某些業務線可能根據業務場景需要採用功能開關釋出,還有一些業務線則可能採用高階的 A/B 測試釋出手段。
六、附錄
-
https://github.com/ContainerSolutions/k8s-deployment-strategies
-
https://opensource.com/article/18/2/feature-flags-ring-deployment-model
-
https://github.com/ctripcorp/apollo
-
http://www.ff4j.org/
-
https://launchdarkly.com/
-
https://github.com/intuit/wasabi
-
https://blog.zenika.com/2017/04/19/migration-dun-legacy-avec-goreplay/
-
https://github.com/buger/goreplay
-
http://blog.shurenyun.com/untitled-9/
-
https://en.wikipedia.org/wiki/A/B_testing
原文連結:https://mp.weixin.qq.com/s/WdCM6cOmjdhAEa6PtviH9A