干貨!微服務(wù)架構(gòu)的理解
1.前言
? ? ?《三國演義》開篇便講道: "話說天下大勢,分久必合,合久必分...."。其實經(jīng)歷的大部分事物都有這樣的規(guī)律, 在軟件系統(tǒng)設(shè)計中,也會經(jīng)歷這樣的迭代演進(jìn)。在兩年多的微服務(wù)架構(gòu)設(shè)計與實戰(zhàn)中,筆者經(jīng)歷了從龐大的單體應(yīng)用系統(tǒng)架構(gòu)拆分成不同的眾多的微服務(wù)應(yīng)用,再將不同的微服務(wù)應(yīng)用重組成有能力復(fù)用的中臺,但總目的都是為了更好地支撐業(yè)務(wù)發(fā)展,提升軟件開發(fā)的效率與質(zhì)量。本篇主要想梳理微服務(wù)架構(gòu)的一些基礎(chǔ)知識,讓大家對微服務(wù)架構(gòu)有個全面系統(tǒng)的了解。
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK
2.單體架構(gòu) VS 微服務(wù)架構(gòu)
2.1 軟件架構(gòu)定義
? ? ? ? ?軟件架構(gòu)是構(gòu)建應(yīng)用系統(tǒng)所需要的一組結(jié)構(gòu),包括軟件元素、元素之間的關(guān)系以及兩者的屬性。其中如何分解軟件元素以及這些元素之間的關(guān)系,變得非常重要。一個好的軟件架構(gòu)具備兩個特點:
合理調(diào)配生產(chǎn)關(guān)系與生產(chǎn)力,讓具備不同專業(yè)知識與技術(shù)棧的的人士都參與到軟件系統(tǒng)開發(fā)中來, 高效地協(xié)同工作;
能讓各個軟件元素有清晰的定義與職責(zé),并有一套良好、高效的交互機(jī)制.
2.2 單體應(yīng)用架構(gòu)
? ? ? ?應(yīng)用開發(fā)采用單體架構(gòu),所有的代碼在一個代碼倉庫中管理,最后打包成一個部署包,運(yùn)行在一個進(jìn)程上。典型的有三層應(yīng)用架構(gòu)與六邊形應(yīng)用架構(gòu)兩種。
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK

在項目初期,單體架構(gòu)確實會給開發(fā)帶來無與倫比的效率提升,單體架有以下的好處:
應(yīng)用開發(fā)簡單,基本所有的代碼都在一個倉庫中管理;
非常方便進(jìn)行大規(guī)模的更改;
容易測試,只需要寫幾個端對端的測試;
部署簡單明了,橫向擴(kuò)展非常容易.

但隨著業(yè)務(wù)的擴(kuò)張,業(yè)務(wù)模塊數(shù)量與代碼量都會急劇增加,這時單體架構(gòu)的弊端逐漸突顯:
復(fù)雜度不斷提升,模塊之間的耦合度越來越高,維護(hù)成本很高;
更新迭代周期變長,從代碼提交到實際部署的周期會拉長,甚至有時都無法交付;
難以擴(kuò)展與迭代演進(jìn),使用過時的技術(shù)棧或組件一直無法升級.
2.3 微服務(wù)架構(gòu)
? ? ? 在講述微服務(wù)架構(gòu)之前一定要講下經(jīng)典的擴(kuò)展立方體理論,擴(kuò)展立方體定義了三種不同的擴(kuò)展應(yīng)用程序的方法:
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK
X軸擴(kuò)展在多個相同實例之間實現(xiàn)請求的負(fù)載均衡;
Y軸擴(kuò)展根據(jù)功能將應(yīng)用程序拆分為服務(wù);?
Z軸擴(kuò)展根據(jù)請求的屬性路由請求.

微服務(wù)架構(gòu)其實可以理解為”模塊化設(shè)計"的擴(kuò)展延伸,只是這些"功能模塊"以單獨(dú)的部署包的方式運(yùn)行在各自的進(jìn)程中。這樣每個服務(wù)之間都是相互獨(dú)立的,并且有自己的私有數(shù)據(jù)庫,兩者之間僅能通過API的方式進(jìn)行通信。

從單體架構(gòu)到微服務(wù)架構(gòu)的演進(jìn)也帶來了以下好處:
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK
從代碼管理來看,每個服務(wù)較小,大部分由于十幾個接口或服務(wù)方法組成,非常容易維護(hù);
從運(yùn)維管理來看,每個服務(wù)都可以獨(dú)立部署,非常易于擴(kuò)展;?
從團(tuán)隊管理來看,可以更好地劃分職責(zé)范圍;
從軟件開發(fā)總體來看,可以使軟件系統(tǒng)可持續(xù)性交付部署.

同樣,微服務(wù)架構(gòu)也具有以下弊端:
服務(wù)的拆分和定義有一定的難度;
增加了系統(tǒng)的復(fù)雜度,使開發(fā)、測試、部署都變得更加困難;
在部署多個服務(wù)的功能時需要在協(xié)調(diào)開發(fā)團(tuán)隊.
3.微服務(wù)架構(gòu)定義與組成
? ? ? ?微服務(wù)架構(gòu)中需要考慮決策模型由多個模式組成。從層次上大致可分為應(yīng)用相關(guān)、應(yīng)用基礎(chǔ)相關(guān)、基礎(chǔ)設(shè)施相關(guān)三大層。
應(yīng)用相關(guān)模式: 服務(wù)拆分、數(shù)據(jù)庫的架構(gòu)、維護(hù)數(shù)據(jù)一致性問題、測試相關(guān);
應(yīng)用基礎(chǔ)設(shè)施相關(guān)模式: 邊界問題、安全性、事務(wù)性消息、通信風(fēng)格、可靠性、可監(jiān)測性;
基礎(chǔ)設(shè)施相關(guān)模式: 應(yīng)用/服務(wù)的部署、服務(wù)發(fā)現(xiàn)等.

3.1 服務(wù)拆分
將原來的單體應(yīng)用系統(tǒng)分解為一系列的服務(wù)其實是有難度的,可以遵循以下兩種分解策略:
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK
根據(jù)業(yè)務(wù)能力分解
根據(jù)子域分解
3.2 通信方式
使用微服務(wù)架構(gòu)的應(yīng)用程序是分布式系統(tǒng),進(jìn)程間通信是重要組成部分,有以下幾種通信模式:
通信風(fēng)格: 使用哪一種的進(jìn)程間通信機(jī)制;
服務(wù)發(fā)現(xiàn): 客戶端如何獲得具體實例的真實IP地址;
可靠性: 在服務(wù)不可用的情況下,如何確保服務(wù)之間的可靠通信;
事務(wù)性消息: 如何將消息發(fā)送、事件發(fā)布、更新業(yè)務(wù)數(shù)據(jù)的數(shù)據(jù)庫事務(wù)集成;
外部API: 應(yīng)用客戶端如何與服務(wù)通信.
3.3 數(shù)據(jù)一致性模式
? ? ? ? 在微服務(wù)架構(gòu)下每個服務(wù)都有自己獨(dú)立的數(shù)據(jù)庫,原先在單應(yīng)用架構(gòu)下的2PC的事務(wù)機(jī)制在微服務(wù)架構(gòu)中就不再適用,需要類似于分布式事務(wù)的中間件來保證數(shù)據(jù)的一致性。
3.4 可觀測性
? ? ? ? 在微服務(wù)架構(gòu)下對,一個請求往往會經(jīng)過多個服務(wù)實例的跳轉(zhuǎn),有關(guān)應(yīng)用程序的性能問題如高延時等問題就比較難觀測與解決,需要以下的模式來設(shè)計出一套可監(jiān)測的服務(wù):
健康檢查API:每個微服務(wù)應(yīng)用需要一個可以返回健康狀體的API;
日志聚合: 把服務(wù)器節(jié)點的所有日志都寫入一個集中式的日志服務(wù)器,可在這個服務(wù)器上進(jìn)行日志搜索,并根據(jù)日志情況出發(fā)告警,典型的方案是Log路徑+容器+ES;
分布式鏈路跟蹤:為每一個外部的請求分配一個唯一的ID,用于在各個服務(wù)之間的跟蹤外部請求,newlic/skywalking;
應(yīng)用指標(biāo): 維護(hù)使用的指標(biāo),如調(diào)用計數(shù);
審計日志: 記錄用戶的行為;
3.5 部署相關(guān)模式
? ? ? ? 部署一個單體應(yīng)用是一個比較直觀的操作,部署基于微服務(wù)的應(yīng)用程序就要復(fù)雜得多,通常應(yīng)有數(shù)十甚至上百個服務(wù)組成。傳統(tǒng)的基于手工復(fù)制到服務(wù)器上的應(yīng)用程序部署方式不再適用于微服務(wù)架構(gòu),需要一個高度自動化部署的基礎(chǔ)設(shè)施,如可以管理需求任務(wù)、代碼變更, 服務(wù)器資源環(huán)境于一身的部署平臺。
3.6 安全相關(guān)
? ? ? ? 在微服務(wù)架構(gòu)中,用戶身份、權(quán)限驗證的工作通常由網(wǎng)關(guān)完成的,常見的解決方式是Outh2協(xié)議的訪問令牌模式,由網(wǎng)關(guān)將訪問令牌傳遞到服務(wù),驗證令牌并獲取用戶有關(guān)的信息。
3.7 測試相關(guān)
? ? ? ? 單體架構(gòu)的測試與微服務(wù)架構(gòu)測試的方法與重點都不一樣,由于服務(wù)粒度變小,微服務(wù)架構(gòu)讓測試變得更加簡單,重點在于測試不同的服務(wù)是否協(xié)同工作,同時使用復(fù)雜的、緩慢和脆弱的端對端的測試來測試多個服務(wù),以下模式可以通過單獨(dú)測試服務(wù)來簡化測試工作量與提升測試的效率:
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK
消費(fèi)端驅(qū)動的測試: 驗證服務(wù)滿足客戶端所期望的功能;
的消費(fèi)端契約測試: 驗證服務(wù)的客戶端可以正常與服務(wù)通信;
服務(wù)組件測試: 在隔離環(huán)境中測試服務(wù).
3.8 基礎(chǔ)設(shè)施和邊界問題的相關(guān)模式
在微服務(wù)架構(gòu)中,每個服務(wù)必須實現(xiàn)許多跟基礎(chǔ)設(shè)施相關(guān)的功能,如可觀測性模式和服務(wù)發(fā)現(xiàn)模式,外部化配置模式等,需要開發(fā)出一個微服務(wù)架構(gòu)的基礎(chǔ)設(shè)施基座,這樣在開發(fā)新的微服務(wù)業(yè)務(wù)時就可以在基座上快速接入與開發(fā)。
4.服務(wù)拆分
當(dāng)時整個后臺系統(tǒng)一樣遇到了“單體地獄”的問題,所以決心拆分成若個領(lǐng)域微服務(wù)來緩解開發(fā)/部署上的一系列問題,主要遵循以下的拆分策略與指導(dǎo)原則。
4.1 拆分策略
? ? ? ? 所有的出發(fā)點都是業(yè)務(wù),首先要梳理出功能需求或用戶故事用來定義出系統(tǒng)操作,然后將系統(tǒng)操作轉(zhuǎn)化成一個個完整的請求,根據(jù)請求就可以初步定義出服務(wù)的具體職責(zé)與邊界,然后再定義服務(wù)之間的接口和協(xié)作方式。

服務(wù)拆分的依據(jù)有兩種:一種是從業(yè)務(wù)能力到服務(wù),對業(yè)務(wù)能力的聚合能力邊界與職責(zé),另一種是根據(jù)DDD領(lǐng)域設(shè)計中的子域進(jìn)行服務(wù)劃分。
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK

4.4 拆分的指導(dǎo)原則
單一職責(zé)任(SRP): 原先指的是每個類只承載一個職責(zé),在微服務(wù)架構(gòu)中,指的是每個微服務(wù)都應(yīng)該是盡可能小的,內(nèi)聚的,并且能獨(dú)立完成一個業(yè)務(wù)的閉環(huán)支撐。
閉包原則(CPP): 定義是包中的所有類應(yīng)該是對同類的變化的一個集合,如果對包做出修改,需要更新的類都應(yīng)該在這個包內(nèi),在微服務(wù)架構(gòu)中, 指的是當(dāng)需求變化時,需要變更的服務(wù)組件范圍是可控的最好是一個服務(wù),最好在一個開發(fā)團(tuán)隊內(nèi)就能完成。
4.5 拆分單體應(yīng)用服務(wù)的難點
網(wǎng)絡(luò)延遲,請求在經(jīng)過服務(wù)的層層轉(zhuǎn)發(fā)后,通信鏈路會增加N倍,當(dāng)然通信會延遲;
進(jìn)程間的通信導(dǎo)致可用性降低,微服務(wù)集群所在的網(wǎng)絡(luò)的流量會增大,哪怕是在局域網(wǎng)內(nèi)也會因為網(wǎng)絡(luò)抖動或鏈路熱點而導(dǎo)致可用性降低;
在服務(wù)之間保持?jǐn)?shù)據(jù)一致,獲取一致的數(shù)據(jù)視圖,不同數(shù)據(jù)庫實例的事務(wù)較難實現(xiàn).
5.進(jìn)程間的通信
5.1 通信的方式
一對一: 每個客戶端請求由一個服務(wù)實例處理;
一對多: 每個客戶端請求由多個服務(wù)實例處理;
同步模式: 客戶端請求需要服務(wù)端實時響應(yīng),客戶端等待響應(yīng)時間可能會阻塞;
異步模式: 客戶端請求不會阻塞進(jìn)程,服務(wù)端的響應(yīng)可以是非實時的;
5.2 基于同步遠(yuǎn)程過程調(diào)用模式的通信
? ? ? ? 遠(yuǎn)程過程調(diào)用的工作原理是,客戶端中的業(yè)務(wù)邏輯調(diào)用代理接口,這個接口由遠(yuǎn)程過程調(diào)用代理適配類實現(xiàn),調(diào)用代理會向服務(wù)發(fā)出請求,該請求由遠(yuǎn)程過程調(diào)用服務(wù)器適配類處理,該類通過接口調(diào)用服務(wù)的業(yè)務(wù)邏輯,然后將回復(fù)發(fā)送回過程調(diào)用代理,該代理將結(jié)果返回給客戶端的業(yè)務(wù)邏輯。

? ? ? ? 在整個遠(yuǎn)程調(diào)用過程中可能會發(fā)生網(wǎng)絡(luò)超時、服務(wù)器端超出了處理的請求數(shù)等問題導(dǎo)致的客戶端請求失敗,可以使用hystrix組件來處理這些問題,保證服務(wù)的高可用,但是基于斷路器模式屬于“后知后覺”型,要實現(xiàn)服務(wù)發(fā)現(xiàn)主要有應(yīng)用服務(wù)與平臺服務(wù)兩種發(fā)現(xiàn)模式。
客戶端發(fā)現(xiàn)模式: 服務(wù)實例使用服務(wù)注冊表組冊其網(wǎng)絡(luò)位置,客戶端從注冊表中獲取到可用服務(wù)實例的列表,并在它們之間進(jìn)行負(fù)載均衡;
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK
平臺層服務(wù)發(fā)現(xiàn)模式: 許多部署瓶體啊如Docker和Kubernetes都具有內(nèi)置的服務(wù)注冊表和服務(wù)發(fā)現(xiàn)機(jī)制,部署平臺為每個服務(wù)提供DNS名稱,虛擬IP地址和DNS名稱,當(dāng)客戶頓啊向DNS名稱和虛擬IP發(fā)出請求,部署平臺自動將其路由到其中一個可用的服務(wù)實例.

5.3 基于異步消息模式的通信
? ? ? ?使用消息機(jī)制時,服務(wù)之間的通信采用異步交換消息的方式完成。發(fā)送方中的業(yè)邏輯調(diào)用發(fā)送接口,該接口封裝底層通信機(jī)制,發(fā)送端由信息發(fā)送適配器類實現(xiàn),該消息發(fā)送適配器類通過消息通道向接收器發(fā)送消息。調(diào)用接收器中的消息處理程序適配器類來處理消息。它調(diào)用接收方業(yè)務(wù)邏輯實現(xiàn)的接收端接口。任意數(shù)量的發(fā)送方都可以向消息通道發(fā)送消息,同樣,任意數(shù)量的接收方都可以從消息通道中接收消息。

6.總結(jié)
? ? ? ? 本篇主要是對微服務(wù)架構(gòu)的一個系統(tǒng)性的介紹,對比了單體應(yīng)用架構(gòu)與微服務(wù)架構(gòu)的優(yōu)缺點,并在微服務(wù)架構(gòu)設(shè)計中的需要重點考慮的方面如服務(wù)拆分、通信模式、可觀測性、安全、部署相關(guān)等等相關(guān)模式,最后簡述了服務(wù)拆分的策略與指導(dǎo)原則、遠(yuǎn)程過程調(diào)用與消息交互兩種主要的進(jìn)程間模式的工作原理。
學(xué)習(xí)更多,請點擊:https://www.bilibili.com/video/BV11541137LX
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1F54y177YZ
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1154y157e5
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1nB4y1w7BT
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://www.bilibili.com/video/BV1tZ4y1F7eK
作者:代碼的色彩
鏈接:https://juejin.cn/post/6960282794081812511
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。