- 微服務(wù)架構(gòu)深度解析:原理、實踐與進(jìn)階
- 王佩華編著
- 4578字
- 2021-07-07 16:03:54
1.2 微服務(wù)主要特性
1.2.1 粒度更細(xì)的服務(wù)
微服務(wù)架構(gòu)相比SOA分布式架構(gòu)強調(diào)按業(yè)務(wù)邊界做細(xì)粒度的服務(wù)拆分。SOA架構(gòu)使用粗粒度的服務(wù)模式來封裝業(yè)務(wù)和技術(shù)能力,減少服務(wù)交互,但同時帶來了業(yè)務(wù)耦合的復(fù)雜性。而微服務(wù)架構(gòu)本質(zhì)上是一個做減法的架構(gòu),將規(guī)模龐大的單體系統(tǒng)進(jìn)行服務(wù)拆分,每個細(xì)粒度服務(wù)的功能和職責(zé)單一。當(dāng)然,服務(wù)的粒度并不是拆得越細(xì)越好,如果拆分不當(dāng),還會造成服務(wù)頻繁地跨網(wǎng)絡(luò)操作,增加系統(tǒng)的整體復(fù)雜性。
首先,微服務(wù)粒度的劃分要求工程師充分理解和洞察業(yè)務(wù)領(lǐng)域的邊界,保證你所拆分的服務(wù)是自包含的。所謂“自包含”就是說你的服務(wù)是可以獨立部署、獨立演進(jìn)的,你的服務(wù)可以自主地完成某個特定的、單一的功能。
其次,細(xì)粒度服務(wù)應(yīng)該同時具備高內(nèi)聚和低耦合兩個特征。高內(nèi)聚要求將系統(tǒng)中相關(guān)的元素和行為聚集在一起,把不相關(guān)的元素和行為放在別處;低耦合是指降低微服務(wù)之間的相互依賴程度和相互作用關(guān)系,如果服務(wù)之間存在緊密聯(lián)系,說明它們的耦合度比較高,最好不要做拆分操作,而應(yīng)該做聚合操作,這樣可以使信息的傳遞和協(xié)作比拆分成獨立的服務(wù)更加簡單可控。
另外,細(xì)粒度服務(wù)應(yīng)該盡量做到獨立。這一特性也適用于單一職責(zé)原則:SRP(Single Responsibility Principle),該原則由Robert C.Martin提出。從面向?qū)ο笤O(shè)計的角度看,所謂職責(zé)是指一個類(Class)變化的原因。如果一個類有多個改變動機,那么這個類就具有多個職責(zé),而單一職責(zé)原則就是指一個類或者模塊應(yīng)該有且只有一個改變原因。
下面總結(jié)一下粒度更細(xì)的服務(wù)帶來的好處:
● 粒度更細(xì)的服務(wù)使每一個服務(wù)專注做好一件事情。每個服務(wù)完成一個單一任務(wù),在功能不變的情況下,應(yīng)用被拆分為多個可管理的服務(wù),很好地解決了系統(tǒng)的復(fù)雜性問題。
● 粒度更細(xì)的服務(wù)有助于新人對工程的學(xué)習(xí)。對于一個大型的、生命周期比較長的項目,人員的流動和組織變化是經(jīng)常發(fā)生的事情,而龐大的單體架構(gòu)容易使模塊之間相互耦合,功能界限模糊,同時增加了新人的學(xué)習(xí)成本。
● 粒度更細(xì)的服務(wù)有利于部署。對于大型單體項目,模塊之間往往存在緊密的代碼耦合,一個子模塊的編譯錯誤往往會導(dǎo)致整個應(yīng)用無法構(gòu)建成功,而細(xì)粒度的服務(wù)可以通過獨立工程解決“牽一發(fā)而動全身”的問題。
● 粒度更細(xì)的服務(wù)具備更好的復(fù)用性。在軟件領(lǐng)域,我們一直提倡使用復(fù)用的方式構(gòu)建系統(tǒng),粒度更細(xì)的服務(wù)通過獨立的部署,通過聲明語言無關(guān)、平臺無關(guān)的標(biāo)準(zhǔn)接口(REST API、gRPC)對外暴露服務(wù),實現(xiàn)了積木式的架構(gòu)搭建模式,提高了軟件整體的開發(fā)效率。
1.2.2 圍繞業(yè)務(wù)劃分團(tuán)隊
傳統(tǒng)的IT企業(yè)習(xí)慣根據(jù)人員掌握的技能來劃分組織。例如,熟悉前端的同事,都集中在一個前端開發(fā)團(tuán)隊;熟悉數(shù)據(jù)庫的同事,一般都會集中在DBA(Database Administrator,數(shù)據(jù)庫管理員)團(tuán)隊;熟悉測試的同事,專門成立一個測試團(tuán)隊專職做測試工作。我們習(xí)慣于將這樣的團(tuán)隊稱為“職能型組織”,它的優(yōu)勢是資源集中,有利于同一職能內(nèi)部的專業(yè)人士交流和經(jīng)驗積累。
然而,職能型組織最大的問題是團(tuán)隊之間不容易協(xié)調(diào)利益沖突,容易形成部門墻或者叫部門壁壘。當(dāng)職能部門有多個項目同時進(jìn)行時,就會產(chǎn)生資源失衡問題,不利于各職能部門之間的溝通交流和團(tuán)結(jié)協(xié)作。業(yè)務(wù)的需求變化如果牽涉多個職能型組織所負(fù)責(zé)的模塊協(xié)作聯(lián)調(diào),往往會出現(xiàn)項目排期問題、優(yōu)先級問題,對于跨地域、跨國家的組織,還會出現(xiàn)時差問題、溝通及文化差異問題,這個時候反而增加了團(tuán)隊之間的溝通和協(xié)調(diào)成本,降低了開發(fā)效率。
微服務(wù)架構(gòu)更加提倡以業(yè)務(wù)為中心,強調(diào)圍繞業(yè)務(wù)領(lǐng)域來劃分團(tuán)隊。團(tuán)隊由具備不同能力象限的人員組成,而這樣的全功能型團(tuán)隊相比職能型團(tuán)隊可以防止人員之間的互相扯皮、互相指責(zé)的問題。同一個團(tuán)隊圍繞業(yè)務(wù)領(lǐng)域溝通效率更高,團(tuán)隊合作更加積極主動,有更強的主人翁意識(Ownership)。從技術(shù)的維度看,微服務(wù)架構(gòu)傾向于在指定范圍的“業(yè)務(wù)界限上下文”中定義標(biāo)準(zhǔn)規(guī)范的交互方式,這樣能夠保證業(yè)務(wù)接口(API)更加穩(wěn)定,在后續(xù)服務(wù)的迭代升級過程中具備更好的業(yè)務(wù)兼容性和可演進(jìn)性。
綜上所述,在圍繞業(yè)務(wù)構(gòu)建微服務(wù)架構(gòu)的時候,解決的一個本質(zhì)問題就是人員分工的問題,正如康威定律所說,任何組織所設(shè)計的系統(tǒng)、所交付的軟件產(chǎn)品方案在結(jié)構(gòu)上都應(yīng)該與該組織的溝通結(jié)構(gòu)和組織方式保持一致。下面是組織結(jié)構(gòu)演進(jìn)示意圖。

1.2.3 技術(shù)多樣性
微服務(wù)架構(gòu)不限定提供服務(wù)方所使用的技術(shù)棧和技術(shù)選型。微服務(wù)架構(gòu)傾向于服務(wù)之間使用標(biāo)準(zhǔn)的輕量級的通信協(xié)議(HTTP)完成服務(wù)的集成和通信。例如,對于性能要求比較高、對網(wǎng)絡(luò)通信效率比較關(guān)注的服務(wù),可以使用C++語言構(gòu)建;對于文本分析性的業(yè)務(wù),可以采用Python腳本語言;而對于企業(yè)應(yīng)用級的Web項目,使用Java語言開發(fā)比較合適??梢?,每一種語言和技術(shù)都有其“擅長”的場景和適合解決的問題。
微服務(wù)架構(gòu)提倡數(shù)據(jù)存儲的多樣性和獨立性。不同的數(shù)據(jù)存儲引擎有各自擅長處理的業(yè)務(wù)類型數(shù)據(jù)。對于公司的核心業(yè)務(wù)即OLTP(On-Line Transaction Processing,聯(lián)機事務(wù)處理)業(yè)務(wù),可能會采用MySQL這樣的關(guān)系型數(shù)據(jù)庫。關(guān)系型數(shù)據(jù)庫的特點是遵循ACID原則[1],對事務(wù)的一致性有更好的支持,通過標(biāo)準(zhǔn)的SQL語言就可以方便地實現(xiàn)結(jié)構(gòu)化數(shù)據(jù)的查詢和更新。
在NoSQL數(shù)據(jù)庫陣營中,對于日志數(shù)據(jù),可以存放在Elasticsearch這樣的LSM樹數(shù)據(jù)結(jié)構(gòu)存儲引擎中,適合日志搜索、查詢操作;對于分布式系統(tǒng)之間的共享數(shù)據(jù),采用Redis這樣的內(nèi)存引擎,在讀寫效率、高并發(fā)性能上有更大的優(yōu)勢;如果是文檔型數(shù)據(jù),使用MongoDB這樣的文檔存儲引擎更加高效便利。下面是采用不同編程語言和技術(shù)棧配合不同的數(shù)據(jù)存儲類型的技術(shù)多樣式示意圖。

微服務(wù)架構(gòu)提倡在技術(shù)多樣性的場景中,選擇最適合的技術(shù)棧。微服務(wù)通過使用標(biāo)準(zhǔn)的API接口對外暴露服務(wù),給嘗試新技術(shù)提供了更加友好的架構(gòu)支持。
然而,很多公司也推崇使用統(tǒng)一的編程語言和標(biāo)準(zhǔn)化的技術(shù)棧。統(tǒng)一技術(shù)棧的優(yōu)勢也是明顯的,首先它會帶來開發(fā)效率的提升;單一技術(shù)棧的維護(hù)成本相對較低;新加入的開發(fā)人員也能夠盡快適應(yīng)統(tǒng)一的編程語言和架構(gòu)風(fēng)格;項目的風(fēng)險相對比多技術(shù)棧有更好的可控性。
即便如此,我們說微服務(wù)架構(gòu)還是向著異構(gòu)化、技術(shù)多樣性的趨勢在發(fā)展,因為只有保持技術(shù)的多樣性,才能保證技術(shù)生態(tài)的生命力。對于技術(shù)棧和技術(shù)選型來說,架構(gòu)師需要一個Trade-off(權(quán)衡利弊)的過程。
1.2.4 去中心化
大型企業(yè)在集成異構(gòu)系統(tǒng)和完成進(jìn)程之間的通信時,一種傳統(tǒng)的架構(gòu)模式就是使用ESB消息總線技術(shù),它可以完成信息路由、業(yè)務(wù)規(guī)則編排、協(xié)議轉(zhuǎn)化等功能。雖然,ESB架構(gòu)改變了傳統(tǒng)軟件的架構(gòu)模式,消除了不同應(yīng)用之間的技術(shù)差異,協(xié)調(diào)了不同應(yīng)用服務(wù)的協(xié)作運行方式,實現(xiàn)了服務(wù)之間的集成和整合,但是,ESB架構(gòu)傾向于使用集中式的架構(gòu)管理模式,它本質(zhì)上是一種中心化的架構(gòu)。我們將這種企業(yè)服務(wù)總線或服務(wù)編配系統(tǒng)的方案稱為“智能管道和啞終端”模式,它會導(dǎo)致業(yè)務(wù)邏輯的中心化和啞服務(wù)問題。
“啞終端”(Dumb Endpoint)會導(dǎo)致ESB消息總線過度復(fù)雜,這種中央式的架構(gòu)模式存在天然的技術(shù)與業(yè)務(wù)耦合問題。業(yè)務(wù)編排和業(yè)務(wù)消息轉(zhuǎn)化能力與業(yè)務(wù)功能全部集中在單一邏輯控制單元中,它并沒有做很好的業(yè)務(wù)封裝,而是將業(yè)務(wù)邏輯的復(fù)雜性全部傳遞到了消息總線中。同時,隨著服務(wù)規(guī)模的擴(kuò)大,中心化架構(gòu)的可擴(kuò)展性會成為一個極大的障礙。業(yè)務(wù)中的職責(zé)邊界不清和ESB中心化的問題還會暴露性能問題,成為系統(tǒng)的瓶頸。
微服務(wù)架構(gòu)摒棄了ESB的設(shè)計理念,在微服務(wù)架構(gòu)中,服務(wù)使用智能端點(Smart Endpoint)模式。智能端點強調(diào)所有的業(yè)務(wù)邏輯應(yīng)該自包含在業(yè)務(wù)內(nèi)部的處理邏輯單元中,它可以確保在服務(wù)限界內(nèi)服務(wù)的內(nèi)聚性,而服務(wù)之間的通信應(yīng)該盡量輕量化和簡單化。同時,微服務(wù)使用啞管道(Dumb Pipe)通信機制,將業(yè)務(wù)無侵入的公共組件抽象出來,封裝在通用的消息基礎(chǔ)設(shè)施中(API網(wǎng)關(guān)、消息中間件等)。
我們把微服務(wù)架構(gòu)這樣的設(shè)計理念稱為“去中心化”。微服務(wù)架構(gòu)傾向于服務(wù)之間訂立標(biāo)準(zhǔn)化的服務(wù)契約,目標(biāo)是通過明確清晰的服務(wù)邊界和服務(wù)契約機制讓服務(wù)可以各自獨立迭代和演進(jìn)。
為了最大化微服務(wù)能帶來的自治性,我們需要給擁有服務(wù)的團(tuán)隊委派決策和控制權(quán)。去中心化管治的最高境界就是亞馬遜所宣揚的“構(gòu)建并運行它”的理念,團(tuán)隊對構(gòu)建的軟件的方方面面負(fù)責(zé)。
1.2.5 自動化運維
微服務(wù)架構(gòu)的采用也引入了很多復(fù)雜性,關(guān)鍵問題是我們不得不管理大量的服務(wù)。微服務(wù)增大了運維負(fù)擔(dān);有更多的東西需要部署,有更多的地方需要監(jiān)控,錯誤自然也成倍增加。而解決這些問題的一個關(guān)鍵方法就是擁抱“自動化文化”。前期花費一定的成本,構(gòu)建支持微服務(wù)的工具是很有意義的,比如,自動化測試保證開發(fā)迭代中的代碼質(zhì)量,使用自動化發(fā)布工具將微服務(wù)部署到各個環(huán)境,使用配置文件來明確不同環(huán)境間的差異,創(chuàng)建自定義鏡像來加快部署,創(chuàng)建全自動化的不可變服務(wù)器。
自動化一直是軟件系統(tǒng)運維的最佳實踐,也是微服務(wù)架構(gòu)強調(diào)的重要特性。云技術(shù)使得底層基礎(chǔ)設(shè)施及運行在之上的組件自動化變得非常簡單。盡管前期投入通常會更高,但從中長期來看,無論是人力運維成本,還是在系統(tǒng)的彈性和性能方面,幾乎總能獲得更多的回報。自動化可以比人更快地修復(fù)、擴(kuò)展和部署系統(tǒng)。
自動化貫穿軟件生命周期的整個過程,在持續(xù)集成領(lǐng)域,我們經(jīng)常使用Jenkins等工具自動構(gòu)建、測試和部署微服務(wù)軟件包。微服務(wù)不僅應(yīng)該自動化部署,還應(yīng)該努力實現(xiàn)金絲雀測試和回滾等過程的自動化。
除非系統(tǒng)負(fù)載幾乎從未發(fā)生變化,否則應(yīng)該根據(jù)負(fù)載的增加對微服務(wù)進(jìn)行自動擴(kuò)展,并根據(jù)負(fù)載的持續(xù)下降進(jìn)行自動收縮。通過擴(kuò)展可以確保服務(wù)仍然可用,通過按比例收縮可以降低成本。
隨著微服務(wù)及云原生架構(gòu)的大規(guī)模推廣和使用,部署和運維的復(fù)雜度會逐漸從業(yè)務(wù)端下沉到以Kubernetes為代表的基礎(chǔ)設(shè)施PaaS平臺,利用云和微服務(wù)架構(gòu),我們可以更加快速地部署和交付我們的服務(wù),圍繞快速交付的基礎(chǔ)設(shè)施建設(shè)是微服務(wù)架構(gòu)規(guī)模化發(fā)展的首要任務(wù)。
1.2.6 快速演進(jìn)
軟件的固有特性隨著時間的推移會變得越來越難以改變,軟件的組成部分會因為各種各樣的問題變得脆弱,難以操作。軟件和現(xiàn)實世界一樣,當(dāng)人類的需求和環(huán)境供給達(dá)到平衡時,世界是美好的,然而當(dāng)這種平衡因為蟲害或者氣候變化被打破時,人類需要向生態(tài)中引入變化,重新建立平衡。對于軟件系統(tǒng),同樣存在這種動態(tài)的平衡,我們需要提早對系統(tǒng)進(jìn)行規(guī)劃和設(shè)計。
盡管很多人喜歡在一個理想的環(huán)境下來討論架構(gòu),然而,對于龐大復(fù)雜的單體架構(gòu),很多因素可能促使我們將混亂引入系統(tǒng)工程:業(yè)務(wù)需求的快速變化、工作任務(wù)的優(yōu)先級沖突、有限的人力資源和預(yù)算、軟件工程師水平的參差不齊、缺乏規(guī)范的開發(fā)流程和部署方式。另外,如果是遺留系統(tǒng),還會存在代碼版本混亂、冗余的代碼邏輯等技術(shù)債務(wù)。這種技術(shù)包袱總會帶來災(zāi)難性的后果。通常,業(yè)務(wù)人員往往不想放棄還在工作的系統(tǒng),而開發(fā)人員,面對單體系統(tǒng)的腐化,只能通過不斷地堆疊功能完成任務(wù)。不停地做加法,架構(gòu)成為塞滿各種功能和修復(fù)邏輯的龐然大物,最終產(chǎn)生破窗效應(yīng)。而這種架構(gòu)上的缺陷也將持續(xù)加重我們的技術(shù)債務(wù),業(yè)務(wù)人員要么忍受這樣糟糕的設(shè)計、不斷地妥協(xié),要么丟棄已有系統(tǒng),推倒重來,這樣的做法對于資源有限的團(tuán)隊和公司來說,顯然是難以承受的。
微服務(wù)架構(gòu)強調(diào)在項目早期將軟件分成若干個階段及不同的模塊,從時間、業(yè)務(wù)維度及架構(gòu)維度上做水平和垂直化的分解。微服務(wù)構(gòu)建的首要任務(wù)就是理解業(yè)務(wù)的問題域,好的架構(gòu)師會充分考慮業(yè)務(wù)領(lǐng)域的內(nèi)聚性,降低業(yè)務(wù)之間的耦合,尋求兩者的平衡,并將架構(gòu)的可擴(kuò)展性作為重要的設(shè)計考量因素。微服務(wù)架構(gòu)的一個特征就是面向架構(gòu)演進(jìn),微服務(wù)架構(gòu)的目標(biāo)正是通過業(yè)務(wù)領(lǐng)域的邊界劃分、通過服務(wù)的隔離來分解問題,逐個擊破,因此微服務(wù)架構(gòu)天然具備了可演進(jìn)性。
- Git Version Control Cookbook
- Visual C++程序設(shè)計學(xué)習(xí)筆記
- 深入理解Django:框架內(nèi)幕與實現(xiàn)原理
- Unreal Engine 4 Shaders and Effects Cookbook
- Expert Data Visualization
- WordPress 4.0 Site Blueprints(Second Edition)
- Beginning C++ Game Programming
- Java編程從入門到精通
- 網(wǎng)絡(luò)數(shù)據(jù)采集技術(shù):Java網(wǎng)絡(luò)爬蟲實戰(zhàn)
- 遠(yuǎn)方:兩位持續(xù)創(chuàng)業(yè)者的點滴思考
- Visual C++程序設(shè)計全程指南
- Parallel Programming with Python
- 深入理解MySQL主從原理
- SQL Server 2012數(shù)據(jù)庫管理與開發(fā)(慕課版)
- Python High Performance(Second Edition)