?譯者 | 陳峻
審校 | 孫淑娟
目前,業(yè)界最常見的軟件范例有:單體(Monolith)和微服務(wù)架構(gòu)兩種類型。兩者的邏輯結(jié)構(gòu)如下圖所示。
通常:
- 微服務(wù)架構(gòu)是將應(yīng)用程序表示為微小的、松散耦合的服務(wù)集合。由于整體的復(fù)雜性被轉(zhuǎn)移到了服務(wù)的協(xié)調(diào)級別上,因此每個服務(wù)都代表了一種業(yè)務(wù)功能,可以更加容易地去定位相關(guān)代碼。
- 而單體架構(gòu)是將幾個離散的功能組成一個單元,作為一個整體進(jìn)行測試、部署和擴(kuò)展。由于所有組件都是相互依賴的,因此通常不能夠單獨(dú)運(yùn)行。這就意味著某個模塊中的錯誤,可能會減慢、甚至破壞整個應(yīng)用程序。
1.微服務(wù)架構(gòu)的優(yōu)點(diǎn)
一直以來,我們都沿用且諳熟單體架構(gòu),下面,我們先主要來討論微服務(wù)架構(gòu)的各項優(yōu)點(diǎn):
- 易于擴(kuò)展
- 應(yīng)用組件相互獨(dú)立
- 有清晰的邊界,并能通過HTTP實(shí)現(xiàn)通信
- 可以使用不同的編程語言和數(shù)據(jù)存儲
- 開發(fā)過程可被分到多個團(tuán)隊
- 可被獨(dú)立部署
- 易于更新和維護(hù)
- 使用較小的代碼庫
2.微服務(wù)架構(gòu)的缺點(diǎn)
- 難以監(jiān)控
- 具有更為復(fù)雜的服務(wù)部署
- 服務(wù)之間的通信需要額外安全加固
- 性能會有所降低
- 鑒于分布式系統(tǒng)的遠(yuǎn)程調(diào)用較慢,因此經(jīng)常存在著編程難度大和失敗的風(fēng)險
- 增加了運(yùn)營的復(fù)雜性
3.何時選擇微服務(wù)
?2001年,面對各種應(yīng)用請求的增加,編碼問題突顯、開發(fā)的延遲、以及服務(wù)間的相互依賴性等問題,Amazon逐漸意識到需要從頭開始重構(gòu)其系統(tǒng),因此它將其單一的應(yīng)用程序分解成小型的、獨(dú)立的特定于服務(wù)(service-specific)的應(yīng)用程序,開創(chuàng)了微服務(wù)的架構(gòu)。該架構(gòu)實(shí)現(xiàn)了由一種服務(wù)接受訂單,另一種服務(wù)生成待購買的推薦商品列表,而第三種服務(wù)負(fù)責(zé)提供簡單的身份驗(yàn)證服務(wù)等模式。正如Martin Fowler早在2015年,針對如何構(gòu)建實(shí)用的軟件,所給出的建議那樣:“幾乎所有成功的微服務(wù)案例都是從拆分一個巨型的單體架構(gòu)開始的。”當(dāng)然,僅僅根據(jù)現(xiàn)代化趨勢來選擇微服務(wù),不一定是正確的。通常,我們認(rèn)為如下的應(yīng)用和代碼設(shè)計需求,更適合企業(yè)選擇轉(zhuǎn)向微服務(wù):
- 繁重的系統(tǒng)負(fù)載,需要與不同的支付系統(tǒng)進(jìn)行交互。
- 用戶需求不斷增長和規(guī)模持續(xù)擴(kuò)大,現(xiàn)有應(yīng)用系統(tǒng)常出現(xiàn)中斷。
- 單體應(yīng)用變得不夠靈活且無法升級。
- 為了在競爭激烈的業(yè)務(wù)環(huán)境中取得成功,需要加快應(yīng)用的開發(fā)和發(fā)布時間,并可在后續(xù)著手進(jìn)行功能的更新與升級。
- 需要實(shí)施人工智能之類高級的商業(yè)智能方案,以獲得更深入、更具競爭力的業(yè)務(wù)數(shù)據(jù)、報告和分析。
- 目前的基礎(chǔ)設(shè)施無法提供所需的橫向可擴(kuò)展性,無法處理大數(shù)據(jù)的處理負(fù)載。
上圖是Amazon在2008年完成的被稱為“死亡之星”的微服務(wù)基礎(chǔ)設(shè)施
4.遷移至微服務(wù)所面臨的挑戰(zhàn)
企業(yè)在從單體架構(gòu)向微服務(wù)架構(gòu)的遷移過程中,往往會遇到各種技術(shù)和組織方面的挑戰(zhàn),因此我們有必要了解與之相伴的各類風(fēng)險:
- 麻煩且耗時。由于從單體應(yīng)用整體遷移到微服務(wù)是非常耗費(fèi)時間和精力的,因此企業(yè)往往選擇以“小步快跑”的方式進(jìn)行分步遷移。如果需要在遷移的過程中引入新的服務(wù)特性,那么開發(fā)團(tuán)隊還要投入更多的精力。
- 成本較高。無論是從開發(fā)與編寫代碼的角度,還是從支持、運(yùn)維、以及更改的角度,遷移到微服務(wù)的成本都比較高。企業(yè)需要在構(gòu)建基礎(chǔ)設(shè)施、開發(fā)文檔、以及重構(gòu)應(yīng)用等方面進(jìn)行大量的投資。
- 由于微服務(wù)是一個分布式系統(tǒng),因此開發(fā)團(tuán)隊需要選擇,并實(shí)現(xiàn)基于消息傳遞或RPC的進(jìn)程間通信機(jī)制。
- 移動代碼庫。為了順利地將數(shù)據(jù)從現(xiàn)有的單體架構(gòu)提取至配合微服務(wù)的數(shù)據(jù)庫和代碼庫,我們有可能需要重構(gòu)其實(shí)現(xiàn)的過程,并通過完備的測試覆蓋率,以避免引入新的bug。
- 組織的轉(zhuǎn)變。為了實(shí)現(xiàn)遷移,企業(yè)需要將現(xiàn)有的大型項目團(tuán)隊,拆分成能夠自主開展工作的小型團(tuán)隊。同時,企業(yè)仍需要保持組織架構(gòu)的一致型。
- 團(tuán)隊?wèi)?yīng)對其服務(wù)負(fù)責(zé)。在完成遷移后,各個團(tuán)隊將擁有自己的代碼庫,一旦出現(xiàn)服務(wù)交付的失敗,他們將不再可以歸咎他人,而需要從自身找原因,動手解決,負(fù)責(zé)到底。
- 此外,在系統(tǒng)不宕機(jī)的情況下進(jìn)行遷移,并保證用戶持續(xù)有權(quán)訪問應(yīng)用程序。這本身就有一定的風(fēng)險。
可見,由于需要一定的資源投入,微服務(wù)架構(gòu)可能并不總是對初創(chuàng)型或中型企業(yè)有利。
5.從審查和分析開始遷移
?正如前文所提到的,從一個單體架構(gòu)遷移到微服務(wù)架構(gòu)不但繁瑣耗時,而且存在著風(fēng)險。那么,我們怎么能夠在遷移之前就認(rèn)定微服務(wù)一定適合本企業(yè)呢?《微服務(wù)遷移模式》一書的作者--Sam Newman,建議開發(fā)人員在動手之前考慮如下三個方面的問題:
- 您希望達(dá)到什么目的?
- 您考慮過使用微服務(wù)的折中方案嗎?
- 您怎么判斷遷移的有效性?
下面,我們根據(jù)Sam Newman的建議,提出一套分析方法:
6.設(shè)定目標(biāo)
- 定義遷移對于業(yè)務(wù)和最終用戶的好處,明確企業(yè)想通過微服務(wù)獲得什么。例如:是為了快速開發(fā)的整體進(jìn)程,還是需要減少服務(wù)的相互依賴、亦或增加正常運(yùn)行時間、以及增強(qiáng)可擴(kuò)展性。
- 同時,我們需要事先預(yù)測系統(tǒng)在完成遷移后的負(fù)載和用戶數(shù)。
7.盤點(diǎn)業(yè)務(wù)與功能現(xiàn)狀
企業(yè)的應(yīng)用架構(gòu)師需要能夠找到關(guān)聯(lián)的代碼對象,并將它們與系統(tǒng)中的業(yè)務(wù)功能相匹配。
- 在現(xiàn)有的單體架構(gòu)中,可能許多函數(shù)由于在其使用域中尚未被明確地定義,或者是業(yè)務(wù)流程的邏輯較為混亂,因此往往無法被直接遷移或替換。例如:某個組件持續(xù)與其他多個組件相關(guān)聯(lián),那么就很難被拆分為多個普通的微服務(wù)。
- 分析當(dāng)前的功能,并考慮對其進(jìn)行優(yōu)化。例如,通過剔除大量不必要的信息,來優(yōu)化數(shù)據(jù)庫的查詢,或者可以直接更換新的硬件,以及通過開發(fā)新的功能,來引入微服務(wù)。
8.團(tuán)隊的能力和折中方案
- 評估團(tuán)隊的DevOps成熟度水平,包括:是否了解DevOps的核心實(shí)踐,是否具備基本的自動化文化?運(yùn)營團(tuán)隊是否支持腳本式部署?是否擁有代碼即基礎(chǔ)設(shè)施?是否已有代碼評審的標(biāo)準(zhǔn)?團(tuán)隊只有具備了這些成熟的開發(fā)和運(yùn)維實(shí)踐能力,才能發(fā)揮微服務(wù)架構(gòu)的優(yōu)勢。
- 由于依賴性在服務(wù)之間創(chuàng)建了連接,模糊了組件的邊界,并導(dǎo)致它們必須組合成單個的模塊功能,因此團(tuán)隊只能嘗試著從應(yīng)用的垂直或水平方向進(jìn)行擴(kuò)展。
- 根據(jù)項目的特點(diǎn),僅分離并遷移諸如:電子郵件的發(fā)送、通知的推送或電話的呼叫等部分受限的功能。當(dāng)然,如果您只想從儀表盤系統(tǒng)內(nèi)剝離出來,從已連接的數(shù)據(jù)庫中收集與分析數(shù)據(jù),進(jìn)而單獨(dú)形成微服務(wù)的話,那么應(yīng)全面考慮相互之間的關(guān)聯(lián)性。
9.選擇可擴(kuò)展平臺
?為了保證在構(gòu)建和遷移至微服務(wù)時,用戶的體驗(yàn)不會受到影響,開發(fā)團(tuán)隊?wèi)?yīng)邀請用戶一起進(jìn)行業(yè)務(wù)需求分析,構(gòu)建詳細(xì)的業(yè)務(wù)邏輯和數(shù)據(jù)流。有時,您可能需要一個專有的平臺來擴(kuò)展微服務(wù)的資源,并能夠支持自動化的調(diào)整。在此方面,您可以使用由云服務(wù)提供商托管的無服務(wù)器類型的基礎(chǔ)設(shè)施,例如:Google Cloud、Microsoft Azure和Amazon Web Services等。
10.考慮創(chuàng)建跨職能團(tuán)隊
?在遷移的過程中,企業(yè)需要團(tuán)結(jié)包括開發(fā)人員、質(zhì)量保證(QA)人員、操作運(yùn)維人員、以及企業(yè)所有者等角色,以微服務(wù)為驅(qū)動,來創(chuàng)建可以從事設(shè)計、構(gòu)建、部署和維護(hù)的服務(wù)型團(tuán)隊,并盡量簡化不必要的審批流程。杰夫·貝索斯曾說:“我們試圖創(chuàng)建一支規(guī)模不超過兩個比薩餅的隊伍。”他稱之為“雙披薩團(tuán)隊規(guī)則”。
?下面,我將向您介紹從單體架構(gòu)遷移到微服務(wù)架構(gòu)的一些值得注意的參考經(jīng)驗(yàn)。
11.定義邊界
?正確的邊界往往是有效的微服務(wù)架構(gòu)的基礎(chǔ)。相反,如果邊界定義錯誤,則可能導(dǎo)致在新的微服務(wù)中,各項功能被頻繁更改,特別是那些提供調(diào)用的微服務(wù)接口,很可能會在隨后的集成測試中持續(xù)“浮動”。而且,由于不同微服務(wù)出自不同的團(tuán)隊,因此它們會牽扯到團(tuán)隊之間的各種反復(fù)協(xié)商與較量。
一個典型的域分離的例子源于軟件公司Istio。由于前期定義不足,在遷移到微服務(wù)后不久,Istio團(tuán)隊便從用戶處得到了各種反饋。他們很快地意識到,微服務(wù)并非像他們最初想象的那么實(shí)用。其主要原因是:所有控制面的服務(wù)都是被一股腦部署和使用的,并且共享著相同的管理和安全域。因此,為了大幅降低Istio的操作復(fù)雜性,以更少的精力滿足業(yè)務(wù)需求,并能夠更容易地開發(fā)出服務(wù)產(chǎn)品,他們決定從微服務(wù)架構(gòu)回歸至單體架構(gòu),并按照相關(guān)的技術(shù)標(biāo)準(zhǔn)來構(gòu)建單體架構(gòu),識別架構(gòu)中的業(yè)務(wù)域邊界,并使用公共的API作為接口,來予以實(shí)施。
12.選擇單體架構(gòu)中可以被遷移的功能
?在遷移之前,一個由工程師和作用域?qū)<医M成的團(tuán)隊,可以通過了解現(xiàn)有的實(shí)現(xiàn)方式、依賴關(guān)系、以及內(nèi)部事件等途徑,來確定哪些功能組可以作為微服務(wù),提供最大的產(chǎn)品價值;而哪些剩下的功能,則可以酌情保留在單體架構(gòu)中。
13.微服務(wù)的獨(dú)立數(shù)據(jù)存儲
每個微服務(wù)都需要有一個數(shù)據(jù)存儲庫,這在某種程度上給分離數(shù)據(jù)的管理增加了難度。由于單個存儲系統(tǒng)很容易因?yàn)槭ネ剑霈F(xiàn)不一致性,因此您需要使用能夠執(zhí)行主數(shù)據(jù)管理(master data management,MDM)的工具。例如,它可以通過檢查每個訂閱者ID的數(shù)據(jù)庫,及時發(fā)現(xiàn)其中是否存在相同的ID。據(jù)此,就算某個服務(wù)停止了工作,它也能夠確保用戶數(shù)據(jù)的安全性。當(dāng)然,最理想的狀況是將數(shù)據(jù)同時存儲在微服務(wù)和單體表中。
14.保留微服務(wù)的代碼
?通常,我們與其在性能良好的微服務(wù)中添加、重寫一段代碼,不如為新的或更改后的代碼創(chuàng)建或部署一個新的微服務(wù)。據(jù)此,我們不但可以簡化新代碼的測試,而且能夠減少現(xiàn)有服務(wù)在微服務(wù)中出錯的可能性。
15.微服務(wù)的單獨(dú)構(gòu)建
?通過對每個微服務(wù)采取單獨(dú)的構(gòu)建,我們可以在存儲庫中,以適當(dāng)?shù)男抻喖墑e獲取組件文件。
16.在容器中部署微服務(wù)
?為了盡量簡化,我們最好使用同一種工具,在容器中部署微服務(wù)。例如,Docker便是被廣為推薦的一種容器標(biāo)準(zhǔn)。
17.典型的成功遷移案例
?Netflix(奈飛)?
為了能夠全天候地運(yùn)營,Netflix需要一種架構(gòu)來優(yōu)化交付速度,并擴(kuò)展到下一個數(shù)據(jù)量級。因此,Netflix決定擺脫數(shù)據(jù)中心里由關(guān)系型數(shù)據(jù)庫所帶來的,在垂直向擴(kuò)展時的單點(diǎn)故障,使用NoSQL數(shù)據(jù)庫對數(shù)據(jù)模型進(jìn)行非規(guī)范化處理。同時,該公司采用了由云服務(wù)提供的高度可靠的、可橫向擴(kuò)展的分布式系統(tǒng),并通過選擇AWS作為云服務(wù)提供商,獲得了大規(guī)模且廣泛的服務(wù)和功能。此外,微服務(wù)架構(gòu)也方便Netflix將系統(tǒng)分成獨(dú)立的服務(wù),其中包括:存儲所有觀看節(jié)目的服務(wù),負(fù)責(zé)每月信用卡支付的服務(wù),以及分析觀看歷史以提供類似電影節(jié)目的服務(wù)。該公司的全部遷移過程耗時整整七年。
?Netflix微服務(wù)基礎(chǔ)設(shè)施的邏輯圖
Wix.com?
由于Wix.com的應(yīng)用程序是彼此連接的,因此系統(tǒng)一旦在某個部分出現(xiàn)問題,都會導(dǎo)致整個系統(tǒng)的崩潰。對此,Wix.com開創(chuàng)了新的集成和端到端測試模式,運(yùn)用JSON/RPC協(xié)議,在SpringMVC的基礎(chǔ)上,構(gòu)建了一套微服務(wù)框架。通過遷移,它們解決了處理微服務(wù)之間的通信、故障與調(diào)試等的技術(shù)債。
Cloud Elements
?Cloud Elements使用諸如Minikube和Docker之類的工具,管理本地和遠(yuǎn)程運(yùn)行的服務(wù)。由于所有的微服務(wù)都在Node.js中,因此他們使用諸如Ava等基于npm的單元測試包,實(shí)現(xiàn)了代碼測試的全覆蓋,以應(yīng)對業(yè)務(wù)的指數(shù)增長,并根據(jù)新增的需求不斷迭代其微服務(wù)。
Best Buy(百思買)
?過去,相互依賴的架構(gòu)造成了Best Buy在業(yè)務(wù)部署上的難題。長時間的宕機(jī)給其在線業(yè)務(wù)的維持帶來了不小的挑戰(zhàn)。開發(fā)團(tuán)隊往往需要把新的功能逐個打包,再累計發(fā)布。如今,他們通過諸如:Chef和Jenkins等工具,實(shí)現(xiàn)了持續(xù)集成與部署,并且將數(shù)據(jù)庫遷移到了Riak(一個分布式NoSQL鍵值數(shù)據(jù)存儲)上。
18.小結(jié)
?綜上所述,我們是否應(yīng)該跟上軟件架構(gòu)的趨勢,放棄單體架構(gòu),投入微服務(wù)的懷抱,目前尚無絕對的定論。我的觀點(diǎn)是:如果目標(biāo)項目既沒有高負(fù)載,又無頻繁地與外部服務(wù)交互的需求,那么我們便可以選擇或維持單體架構(gòu);而如果系統(tǒng)必須在大量的負(fù)載和服務(wù)請求下工作,那么微服務(wù)架構(gòu)會是更好的選擇。
我們再來看企業(yè)的組織結(jié)構(gòu)層面。如果貴公司只有一個開發(fā)團(tuán)隊,那么建議您集中精力構(gòu)建和維護(hù)單體架構(gòu);但是如果您有幾個IT團(tuán)隊,可以同時開發(fā)同一個產(chǎn)品的話,微服務(wù)會比較合適一些。
客觀而言,微服務(wù)架構(gòu)有利有弊,它只是構(gòu)建軟件的另一種方式。是否應(yīng)該選擇完全取決于應(yīng)用程序的業(yè)務(wù)需求。當(dāng)然,您也可以從一個簡單的單體架構(gòu)開始,隨著服務(wù)需求的增長,慢慢將應(yīng)用組件獨(dú)立出來,并遷移到微服務(wù)中。這可能是更為穩(wěn)妥的應(yīng)用實(shí)踐。
原文鏈接:https://dzone.com/articles/Monolith-vs-microservices-architecture-split-or-no
譯者介紹
陳峻 (Julian Chen),51CTO社區(qū)編輯,具有十多年的IT項目實(shí)施經(jīng)驗(yàn),善于對內(nèi)外部資源與風(fēng)險實(shí)施管控,專注傳播網(wǎng)絡(luò)與信息安全知識與經(jīng)驗(yàn);持續(xù)以博文、專題和譯文等形式,分享前沿技術(shù)與新知;經(jīng)常以線上、線下等方式,開展信息安全類培訓(xùn)與授課。?