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