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