譯者 | 陳峻
審校 | 孫淑娟
讓我們來設想一個由數十個可持續部署(continuously-deployed)的自治服務所組成的微服務應用。該應用程序的每個服務群都有自己的存儲庫。它們擁有不同的版本控制方案,并由不同的團隊在不斷發布著新的版本。那么,由于變更歷史分散在這數十個存儲庫中,我們該如何有效地跟蹤變更,獲悉其不同的版本,以及管理應用的發布呢?
想必這是任何使用微服務架構的團隊,都需要處理的問題。下面,我將和您討論可以用來管理微服務發布的兩種不同方法。
通用方法:一個微服務配一個存儲庫
目前,使用微服務架構的應用通常會采用multirepo(多存儲庫)這一最常見的方法,即:
1. 設計一些可被分解為微服務。
2. 為每一個微服務創建一個單獨的存儲庫。
3. 讓每個存儲庫都有一個獨立的CI/CD管道,用于將微服務持續部署到生產環境中。
這種細粒度的持續部署形式可以被稱為微部署。通過微部署,微服務版本可以被獨立地進行部署,而且幾乎不需要任何集成測試。
每個微服務都有一個單獨的CI/CD管道
可以說,微部署是將代碼組織成為多存儲庫的必然結果。上圖展示了目前Semaphore CI/CD部署微服務的方式。
維護多個發布
持續的微部署非常適合那些由Netflix或Semaphore CI/CD等平臺托管的應用。在此類應用中,用戶或客戶不知道、也并不感興趣其幕后運行的單個微服務的版本。然而,對于運行在本地(on-premise)的相同應用而言,持續部署并不能起作用。對此,我們只能發布包含了固定在特定版本中的一組微服務。例如,您可以使用Semaphore On-Premise在防火墻的后面,運行全功能版本的Semaphore CI/CD。
針對托管式應用的微部署,應結合產品的本地實例的發布
通常,我們可以按照如下步驟,發布被組織成multirepos的應用:
1. 在每個repo(存儲庫)中,標記那些有待發布的微服務版本。
2. 針對每個微服務,構建一個Docker鏡像,并將微服務的版本映射到鏡像標簽上。
3. 在單獨的測試環境中,使用集成測試、驗收測試,甚至是手動測試等方式,全面測試有待發布的版本。
4. 在更新文檔之前,檢查每個存儲庫,并為發布的變更日志(changelog),編譯相應的變更列表。
5. 識別舊版本所需的各種熱修補程序。
6. 發布版本。
鑒于一個應用可以包含數十個微服務(和存儲庫),我們很容易看出,該發布方式會導致大量重復的管理開銷。
使用Monorepos(單存儲庫)管理發布
顯然Multirepos更適合于持續部署。而對于那些非定期、非持續的發布,我們需要將所有微服務集合到一個共享的存儲庫中。這便是Google、Airbnb和Uber等大公司,多年以來一直使用的Monorepo方法。
Monorepo包含了所有微服務和統一的CI/CD部署管道
Monorepo策略會讓微服務感覺更像是一個單體應用,其好處在于:
- 讓創建一個發布就像創建某個分支和使用標簽一樣簡單。
- 單個CI/CD流程可標準化測試和部署。
- 更容易實現集成和驗收測試。
- 單個Git歷史更易于理解,并簡化了編寫變更日志和更新文檔的過程。
由一個CI/CD來統管所有
針對變更的Monorepo模式的主要特點體現在如下方面:
- 由于所有變更都被提交到一處,所以CI(持續集成)服務器會承受更大的壓力。我們可以通過使用??基于變更的執行???(change-based execution)或諸如:??Bazel???、??Pants??之類的Monorepo感知工具,來處理此類問題。
- 由于Git沒有內置的代碼保護功能,因此如果需要加固應用的安全性,則可以使用諸如:Bitbucket或??GitHub CODEOWNERS??之類的功能。
- 當測試套件跨越多個單獨的服務時,人們很難在CI的構建中發現和處理錯誤。對此,??測試報告??等功能可協助識別和分析問題。
- Monorepo的CI/CD配置可能會出現許多重復的部分。對此,我們可以使用環境變量或參數化管道,來減少樣板文件(Boilerplate)。
不要忘了可恢復性
到目前為止,我們只關注了應用的可發布性,下面我們再來關注可恢復性。
版本控制不僅能讓我們實現協作、共享知識、跟蹤代碼、以及管理變更,還提供了在出現問題時的恢復能力。只要我們可以訪問到項目中的任何一個變更,便可以“閃回”到任意版本。
不過,由于Multirepos沒能記錄微服務之間的關系,即:沒有任何給定時間點,在生產環境中運行的服務版本的快照,因此,我們若要診斷某些集成類問題,則非常耗時。在某些情況下,我們甚至無法通過回滾微服務來解決問題。
Multirepos在查找失敗的根本原因時具有挑戰性,有時很難找到“最后一次使用過的微服務配置”
而Monorepo能夠輕松地捕獲系統的完整快照,以便為我們提供項目的歷史記錄中任意點所需的所有細節,進而在出現問題時,找到合適的回撤點。
Monorepo具有返回項目歷史中任何時間點所需的微服務關系的詳細信息
小結
綜上所述,到底是應該采取為一個微服務配置一個管道和一個存儲庫,還是配置一個全局管道和一個共享村庫,目前尚無絕對的定論。如果您的微服務是松耦合的話,那么Multirepo和Monorepo都可以正常工作。當然,Multirepos的負載雖大,但可以為您提供更多的自主權。而如果您的服務存在著耦合關系,那么您最好使用Monorepo來保證其可恢復性。
在上文提到的Semaphore平臺中,持續的微部署方式能夠達到較好的效果。但是在Semaphore On-Premise中,我建議您將核心的微服務遷移到Monorepo處。
譯者介紹
陳峻 (Julian Chen),51CTO社區編輯,具有十多年的IT項目實施經驗,善于對內外部資源與風險實施管控,專注傳播網絡與信息安全知識與經驗。
原文標題:??Release Management for Microservices: Multi vs. Monorepos??,作者:Tomas Fernandez