一、微服務(wù)簡(jiǎn)介
A.單體地獄
1.成功的應(yīng)用有一個(gè)趨勢(shì),隨著時(shí)間推移而變得越來(lái)越臃腫
2.復(fù)雜的單體應(yīng)用本身就是持續(xù)部署的障礙
3.單體應(yīng)用使得采用新框架和語(yǔ)言變得非常困難
B.微服務(wù) — 解決復(fù)雜問(wèn)題
1.思路是將應(yīng)用程序分解成一套較小的互連服務(wù)。一個(gè)服務(wù)通常實(shí)現(xiàn)了一組不同的特性或功能。每個(gè)微服務(wù)都是一個(gè)迷你應(yīng)用,包括了業(yè)務(wù)邏輯以及多個(gè)適配器
2.一些微服務(wù)會(huì)暴露一個(gè)供其他微服務(wù)或應(yīng)用客戶端消費(fèi)的API,其他微服務(wù)可能實(shí)現(xiàn)了一個(gè)WebUI,在運(yùn)行時(shí),每個(gè)實(shí)例通常是一個(gè)云虛擬機(jī)(virtual machine,VM)或者一個(gè)Docker容器
3.他們之間的通信是由一個(gè)被稱(chēng)為API網(wǎng)關(guān)(API Gateway)的中介負(fù)責(zé),API網(wǎng)關(guān)負(fù)責(zé)負(fù)載均衡、緩存、訪問(wèn)控制、API計(jì)量和監(jiān)控
4.如果您想從微服務(wù)中受益,每一個(gè)服務(wù)都應(yīng)該有自己的數(shù)據(jù)庫(kù)模式,因?yàn)樗軐?shí)現(xiàn)松耦合
C.微服務(wù)的優(yōu)點(diǎn)
1.解決了復(fù)雜問(wèn)題,把可能會(huì)變得龐大的單體應(yīng)用程序分解成一套服務(wù)
2.這種架構(gòu)使得每個(gè)服務(wù)都可以由一個(gè)團(tuán)隊(duì)獨(dú)立專(zhuān)注開(kāi)發(fā)
3.微服務(wù)架構(gòu)模式可以實(shí)現(xiàn)每一個(gè)微服務(wù)獨(dú)立部署
4.微服務(wù)架構(gòu)模式使得每個(gè)服務(wù)能夠獨(dú)立擴(kuò)展
D.微服務(wù)的缺點(diǎn)
1.微服務(wù)這個(gè)術(shù)語(yǔ)的重點(diǎn)過(guò)多偏向于服務(wù)的規(guī)模,有些開(kāi)發(fā)者主張構(gòu)建極細(xì)粒度的10至100LOC(代碼行)服務(wù),但小型服務(wù)只是一種手段,目標(biāo)在于充分分解應(yīng)用程序以方便應(yīng)用敏捷開(kāi)發(fā)和部署
2.微服務(wù)是一個(gè)分布式系統(tǒng),使得整體變得復(fù)雜,開(kāi)發(fā)者需要選擇和實(shí)現(xiàn)基于消息或者RPC的進(jìn)程間通信機(jī)制,模塊間通過(guò)語(yǔ)言級(jí)方法/過(guò)程調(diào)用相互調(diào)用,這比單體應(yīng)用要復(fù)雜得多
3.分區(qū)數(shù)據(jù)庫(kù)架構(gòu),需要更新不同服務(wù)所用的數(shù)據(jù)庫(kù),通常不會(huì)選擇分布式事務(wù),不僅僅是因?yàn)镃AP定理
4.測(cè)試微服務(wù)應(yīng)用程序也很復(fù)雜,需要啟動(dòng)該服務(wù)及其所依賴的所有服務(wù),或者至少為這些服務(wù)配置存根
5.實(shí)現(xiàn)了跨越多服務(wù)變更,在微服務(wù)中需要仔細(xì)規(guī)劃和協(xié)調(diào)出現(xiàn)的變更至每個(gè)服務(wù)
6.部署基于微服務(wù)的應(yīng)用程序也是非常復(fù)雜的
7.每個(gè)服務(wù)都有多個(gè)運(yùn)行時(shí)實(shí)例,還有更多的移動(dòng)部件需要配置、部署、擴(kuò)展和監(jiān)控,還需要實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)機(jī)制,使得服務(wù)能夠發(fā)現(xiàn)需要與之通信的任何其他服務(wù)的位置(主機(jī)和端口),需要開(kāi)發(fā)人員能高度控制部署方式和高度自動(dòng)化
二、使用API網(wǎng)關(guān)
A.客戶端與微服務(wù)直接通信
1.問(wèn)題:客戶端的需求與每個(gè)微服務(wù)暴露的細(xì)粒度的API不匹配,公網(wǎng)下效率低下
2.問(wèn)題:有可能使用了非web友好協(xié)議,一個(gè)服務(wù)可能使用了Thrift二進(jìn)制rpc,而另一個(gè)可能使用AMQP消息協(xié)議,這些對(duì)瀏覽器還是防火墻都是不友好的,最好是在內(nèi)部使用
3.缺點(diǎn):難以重構(gòu)微服務(wù)
B.使用API網(wǎng)關(guān)
1.API網(wǎng)關(guān)是一個(gè)服務(wù)器,是系統(tǒng)的單入口點(diǎn),類(lèi)似于面向?qū)ο笤O(shè)計(jì)模式中的門(mén)面(Facade)模式,封裝了內(nèi)部系統(tǒng)架構(gòu),并針對(duì)每個(gè)客戶端提供一個(gè)定制API,還可用于認(rèn)證、監(jiān)控、負(fù)載均衡、緩存和靜態(tài)響應(yīng)處理
2.API網(wǎng)關(guān)負(fù)責(zé)請(qǐng)求路由、組合和協(xié)議轉(zhuǎn)換,通常會(huì)調(diào)用多個(gè)微服務(wù)和聚合結(jié)果來(lái)處理一個(gè)請(qǐng)求,可以在Web協(xié)議(如HTTP和WebSocket)和用于內(nèi)部的非Web友好協(xié)議之間進(jìn)行轉(zhuǎn)換
3.API還可以為每個(gè)客戶端提供一個(gè)定制API,通常為客戶端暴露一個(gè)粗粒度的API
C.API網(wǎng)關(guān)的優(yōu)點(diǎn)與缺點(diǎn)
1.主要好處是它封裝了應(yīng)用程序的內(nèi)部結(jié)構(gòu),客戶端只與網(wǎng)關(guān)通信,而不必調(diào)用特定的服務(wù)
2.缺點(diǎn)是它是另一個(gè)高度可用的組件,需要開(kāi)發(fā)、部署和管理,API網(wǎng)關(guān)可能會(huì)成為開(kāi)發(fā)瓶頸
3.重要的是更新API網(wǎng)關(guān)的過(guò)程應(yīng)盡可能地放緩一些,否則,開(kāi)發(fā)人員將被迫排除等待網(wǎng)關(guān)更新
D.實(shí)施API網(wǎng)關(guān)
1.在一個(gè)支持異步、非阻塞I/O平臺(tái)上構(gòu)建API網(wǎng)關(guān)是很有必要的。Node.js、Nginx Plus
2.API網(wǎng)關(guān)通過(guò)簡(jiǎn)單地把他們(請(qǐng)求)路由到適當(dāng)?shù)暮蠖朔?wù)來(lái)處理一些請(qǐng)求。它通過(guò)調(diào)用多個(gè)后端服務(wù)并聚合結(jié)果來(lái)處理其他請(qǐng)求,API網(wǎng)關(guān)應(yīng)該并發(fā)執(zhí)行獨(dú)立請(qǐng)求
3.使用傳統(tǒng)的異步回調(diào)方式來(lái)編寫(xiě)API組合代碼會(huì)很快使您陷入回調(diào)地獄,好的方式是使用響應(yīng)式方法以聲明式編寫(xiě)API網(wǎng)關(guān)代碼
4.一個(gè)基于微服務(wù)的應(yīng)用程序是一個(gè)分布式系統(tǒng),必須使用一個(gè)進(jìn)程間(inter-process)通信機(jī)制,有兩種方案:一是使用基于消息的異步機(jī)制,如JMS、AMQP、ZeroMQ等;另一種采用了同步機(jī)制,如HTTP和Thrift;API網(wǎng)關(guān)需要支持各種通信機(jī)制
5.API網(wǎng)關(guān)需要知道與其通論的每個(gè)微服務(wù)的位置(IP地址和端口),需要使得系統(tǒng)的服務(wù)發(fā)現(xiàn)機(jī)制:服務(wù)端發(fā)現(xiàn)或客戶端發(fā)現(xiàn),API網(wǎng)關(guān)必須能夠查詢服務(wù)注冊(cè)中心,該注冊(cè)中心是所有微服務(wù)實(shí)例及其位置的數(shù)據(jù)庫(kù)
6.當(dāng)一個(gè)服務(wù)調(diào)用另一個(gè)響應(yīng)緩慢或不可用的服務(wù)時(shí),API網(wǎng)關(guān)不應(yīng)該無(wú)期限地等待下游服務(wù),如何處理故障問(wèn)題取決于決定的方案和哪些服務(wù)發(fā)生故障
7.如果可以,API網(wǎng)關(guān)還可以返回緩存數(shù)據(jù),通過(guò)返回默認(rèn)數(shù)據(jù)或緩存數(shù)據(jù),確保系統(tǒng)發(fā)生故障時(shí)最小程度上影響到用戶體驗(yàn)
8.Netflix Hystrix是一個(gè)非常有用的用于編寫(xiě)調(diào)用遠(yuǎn)程服務(wù)代碼的庫(kù)
三、進(jìn)程間通信
A.簡(jiǎn)介
1.服務(wù)必須通過(guò)進(jìn)程間通信(IPC)機(jī)制進(jìn)行交互
B.交互方式
1.第一類(lèi):
* 一對(duì)一,每個(gè)客戶端請(qǐng)求都由一個(gè)服務(wù)實(shí)例處理
* 一對(duì)多,每個(gè)請(qǐng)求由多個(gè)服務(wù)實(shí)例處理
2.第二類(lèi):
* 同步,客戶端要求服務(wù)及時(shí)響應(yīng),在等待過(guò)程中可能會(huì)發(fā)生阻塞
* 異步,客戶端在等待響應(yīng)時(shí)不會(huì)發(fā)生阻塞,但響應(yīng)(如果有)不一事實(shí)上立即返回

3.一對(duì)一交互,包括同步(請(qǐng)求/響應(yīng))與異步(通知與請(qǐng)求/異步響應(yīng)):
* 請(qǐng)求/響應(yīng),客戶端向服務(wù)發(fā)出請(qǐng)求并等待響應(yīng)??蛻舳艘箜憫?yīng)及時(shí)到達(dá)。在基于純種的應(yīng)用程序中,發(fā)出請(qǐng)求的線程可能在等待時(shí)發(fā)生阻塞
* 通知(又稱(chēng)為單向請(qǐng)求),客戶端向服務(wù)發(fā)送請(qǐng)求,但不要求響應(yīng)
* 請(qǐng)求/異步響應(yīng),客戶端向服務(wù)發(fā)送請(qǐng)求,服務(wù)異步響應(yīng)??蛻舳嗽诘却龝r(shí)不發(fā)生阻止,適用于假設(shè)響應(yīng)可能不會(huì)立即到達(dá)的場(chǎng)景
4.一對(duì)多交互,異步類(lèi)型:
* 發(fā)布/訂閱客戶端,發(fā)布通知消息,由零個(gè)或多個(gè)感興趣的服務(wù)消費(fèi)
* 發(fā)布/異步響應(yīng),客戶端發(fā)布請(qǐng)求消息,之后等待一定時(shí)間來(lái)接收消費(fèi)者的響應(yīng)
C.定義API
1.無(wú)論使用何種IPC機(jī)制,使用接口定義語(yǔ)言(interface definition language,IDL)來(lái)嚴(yán)格定義服務(wù)API都是非常有必要的
2.在對(duì)需要實(shí)現(xiàn)的服務(wù)API定義進(jìn)行迭代之后,可以通過(guò)編寫(xiě)接口定義并與客戶端開(kāi)發(fā)人員進(jìn)行審閱來(lái)開(kāi)始開(kāi)發(fā)服務(wù)
D.演化API
1.需要逐步部署服務(wù)的新版本,以便新舊版本的服務(wù)同時(shí)運(yùn)行
2.如果使用了基于HTTP的機(jī)制(如REST),一種方法是將版本號(hào)嵌入到URL中
E.處理局部故障
1.處理局部故障的策略:
* 網(wǎng)絡(luò)超時(shí),不要無(wú)限期地阻塞,始終使用超時(shí)方案
* 限制未完成的請(qǐng)求數(shù)量,對(duì)客戶端擁有特定服務(wù)的未完成請(qǐng)求的數(shù)量設(shè)置上限
* 斷路器模式,追蹤成功和失敗請(qǐng)求的數(shù)量。如果錯(cuò)誤率超過(guò)配置閾值,則斷開(kāi)斷路器
* 提供回退,請(qǐng)求失敗時(shí)執(zhí)行回退邏輯
F.IPC技術(shù)
1.基于HTTP的REST或Thrift
2.異步、基于消息的通信機(jī)制,如AMQP或STOMP
3.基于文本的格式,如JSON或XML
4.使用如Avro或Protocol Buffers等二進(jìn)制格式(更加高效)
G.異步、基于消息的通信
1.客戶端通過(guò)發(fā)送消息向服務(wù)發(fā)出請(qǐng)求,如果服務(wù)需要回復(fù),則通過(guò)向客戶端發(fā)送一條單獨(dú)的消息來(lái)實(shí)現(xiàn),由于通信是異步的,因此客戶端不會(huì)阻塞等待回復(fù),客戶端被假定不會(huì)立即收到回復(fù)
2.兩種通道
* 點(diǎn)對(duì)點(diǎn)通道,發(fā)送一條消息給一個(gè)確切的、正在從通道讀取消息的消費(fèi)者
* 發(fā)布訂閱通道,將每條消息傳遞給所有已訂閱的消費(fèi)者
3.大量的開(kāi)源消息系統(tǒng):RabbitMQ、Apache Kafka、Apache ActiveMQ、NSQ
4.使用消息傳遞的優(yōu)點(diǎn):
* 將客戶端與服務(wù)分離,服務(wù)實(shí)例對(duì)客戶端而言是透明的,客戶端不需要使用發(fā)現(xiàn)機(jī)制來(lái)確定服務(wù)實(shí)例的位置
* 消息緩沖,將消息寫(xiě)入通道隊(duì)列,直到消費(fèi)者處理它們
* 靈活的客戶端—服務(wù)交互
* 毫無(wú)隱瞞的進(jìn)程間通信
5.缺點(diǎn):
* 額外的復(fù)雜操作,消息傳遞系統(tǒng)是一個(gè)需要安裝、配置和操作的系統(tǒng)組件。消息代理必須高度可用
* 實(shí)施基于請(qǐng)求/響應(yīng)式交互的復(fù)雜性
H.同步的請(qǐng)求/響應(yīng)IPC
1.客戶端向服務(wù)器發(fā)送請(qǐng)求,該服務(wù)處理該請(qǐng)求并返回響應(yīng)
2.兩種流行協(xié)議分別是REST和Thrift
3.REST
* 資源是REST的關(guān)鍵概念,通常表示業(yè)務(wù)對(duì)象或業(yè)務(wù)對(duì)象的集合
* 使用HTTP動(dòng)詞(謂詞)來(lái)操縱資源,通過(guò)URL引用
* REST成熟度模型:
* 級(jí)別0的API客戶端通過(guò)向其唯一的URL端點(diǎn)發(fā)送HTTP POST請(qǐng)求來(lái)調(diào)用該服務(wù),每個(gè)請(qǐng)求都被指定要執(zhí)行的操作、操作的目標(biāo)(如業(yè)務(wù)對(duì)象)以及參數(shù)
* 級(jí)別1的API支持資源概念
* 級(jí)別2的API使用HTTP動(dòng)詞(謂詞)執(zhí)行操作:GET檢索、POST創(chuàng)建、PUT更新
* 級(jí)別3的API基于非常規(guī)命名原則設(shè)計(jì),基本思想是GET請(qǐng)求返回的資源的表述,包含用于執(zhí)行該資源上允許的操作的鏈接
* 使用基于HTTP的協(xié)議的好處:
* 簡(jiǎn)單易懂
* 可以使用瀏覽器來(lái)測(cè)試 HTTP API
* 直接支持請(qǐng)求/響應(yīng)式通信
* 屬于防火墻友好
* 不需要中間代碼,簡(jiǎn)化系統(tǒng)架構(gòu)
* 缺點(diǎn):
* 僅直接支持請(qǐng)求/響應(yīng)的交互方式
* 因?yàn)橹苯油ㄐ?,所以必須在交換期間都運(yùn)行著
* 必須知道每個(gè)服務(wù)實(shí)例的位置(即URL)
4.Thrift
* 是一個(gè)用于編寫(xiě)跨語(yǔ)言RPC客戶端和服務(wù)器skeleton,由一個(gè)或多個(gè)服務(wù)組成,定義類(lèi)假于一個(gè)Java接口,是強(qiáng)類(lèi)型方法的集合
* 支持多種消息格式:JSON、二進(jìn)制和壓縮二進(jìn)制
I.消息格式
1.兩種主要的消息格式
* 文本:JSON、XML,人類(lèi)可讀,自描述
* 二進(jìn)制:二進(jìn)制Thrift,Protocol Buffers和Apache Avro
四、服務(wù)發(fā)現(xiàn)
A.為何使用服務(wù)發(fā)現(xiàn)
1.服務(wù)實(shí)例具有動(dòng)態(tài)分配的網(wǎng)絡(luò)位置。此外,由于自動(dòng)擴(kuò)縮、故障與升級(jí),整級(jí)服務(wù)實(shí)例會(huì)動(dòng)態(tài)變更。因此,您的客戶端代碼需要使用更精確的服務(wù)發(fā)現(xiàn)機(jī)制
2.兩種主要的服務(wù)發(fā)現(xiàn)模式:客戶端發(fā)現(xiàn)(client-side discovery)與服務(wù)端發(fā)現(xiàn)(server-side discovery)
B.客戶端發(fā)現(xiàn)模式
1.客戶端負(fù)責(zé)確定可用服務(wù)實(shí)例的網(wǎng)絡(luò)位置和請(qǐng)求負(fù)載均衡??蛻舳瞬樵兎?wù)注冊(cè)中心(service registry),它是可用服務(wù)實(shí)例的數(shù)據(jù)庫(kù),之后,客戶端利用負(fù)載均衡算法選擇一個(gè)可用的服務(wù)實(shí)例并發(fā)出請(qǐng)求
2.服務(wù)實(shí)例的網(wǎng)絡(luò)位置在服務(wù)注冊(cè)中心啟動(dòng)時(shí)被注冊(cè),當(dāng)實(shí)例終止時(shí),它將從服務(wù)注冊(cè)中心移除,通常使用心跳機(jī)制周期性地刷新服務(wù)實(shí)例的注冊(cè)信息

3.優(yōu)點(diǎn):相對(duì)簡(jiǎn)單,可以實(shí)現(xiàn)智能的,特定于應(yīng)用程序的負(fù)載均衡決策
4.缺點(diǎn):將客戶端與服務(wù)注冊(cè)中心耦合在一起,必須為服務(wù)客戶端使用的每種編程語(yǔ)言和框架實(shí)現(xiàn)客戶端服務(wù)發(fā)現(xiàn)邏輯
5.Netflix OSS提供了一個(gè)很好的客戶端發(fā)現(xiàn)模式示例,Netflix Eureka是一個(gè)服務(wù)注冊(cè)中心,Netflix Ribbon是一個(gè)IPC客戶端,用于在可用服務(wù)實(shí)例之間請(qǐng)求負(fù)載均衡
C.服務(wù)端發(fā)現(xiàn)模式
1.客戶端通過(guò)負(fù)載均衡器向服務(wù)發(fā)出請(qǐng)求,負(fù)載均衡器查詢服務(wù)注冊(cè)中心并將每個(gè)請(qǐng)求路由到可用的服務(wù)實(shí)例,服務(wù)實(shí)例由服務(wù)注冊(cè)中心注冊(cè)與銷(xiāo)毀

2.AWS Elastic Load Balancer(ELB)是一個(gè)服務(wù)端發(fā)現(xiàn)路由示例
3.HTTP服務(wù)器和負(fù)載均衡器(如Nginx Plus和Nginx)也可以作為服務(wù)端發(fā)現(xiàn)負(fù)載均衡器
4.優(yōu)點(diǎn):把發(fā)現(xiàn)的細(xì)節(jié)從客戶端抽象出來(lái),消除了為服務(wù)客戶端使用的每種編程語(yǔ)言和框架都實(shí)現(xiàn)發(fā)現(xiàn)邏輯的必要性
5.缺點(diǎn):除非負(fù)載均衡器由部署環(huán)境提供,否則您需要引入這個(gè)高可用系統(tǒng)組件,并進(jìn)行設(shè)置和管理
D.服務(wù)注冊(cè)中心
1.服務(wù)注冊(cè)中心(service registry)是服務(wù)發(fā)現(xiàn)的一個(gè)關(guān)鍵部分,是一個(gè)包含了服務(wù)實(shí)例網(wǎng)絡(luò)位置的數(shù)據(jù)庫(kù)。服務(wù)注冊(cè)中心由使用了復(fù)制協(xié)議(replication protocol)來(lái)維護(hù)一致性的服務(wù)器集群組成
2.Netflix Eureka、etcd、Consul、Apache ZooKeeper
E.服務(wù)注冊(cè)方式
1.服務(wù)實(shí)例自我注冊(cè),即自注冊(cè)模式
2.使用其他系統(tǒng)組件來(lái)管理服務(wù)實(shí)例的注冊(cè),即第三方注冊(cè)模式
F.自注冊(cè)模式
1.服務(wù)實(shí)例負(fù)責(zé)在服務(wù)注冊(cè)中心注冊(cè)和注銷(xiāo)自己。如果有必要,服務(wù)實(shí)例通過(guò)發(fā)送心跳請(qǐng)求來(lái)防止其注冊(cè)信息過(guò)期
2.好處是相對(duì)簡(jiǎn)單,不需要任何其他系統(tǒng)組件,缺點(diǎn)是它將服務(wù)實(shí)例與服務(wù)注冊(cè)中心耦合
G.第三方注冊(cè)模式
1.服務(wù)實(shí)例不負(fù)責(zé)再向服務(wù)注冊(cè)中心注冊(cè)自己,該工作將由被稱(chēng)為服務(wù)注冊(cè)器(service register)的另一系統(tǒng)組件負(fù)責(zé)
2.服務(wù)注冊(cè)器通過(guò)輪詢部署環(huán)境或訂閱事件來(lái)跟蹤運(yùn)行實(shí)例集的變更情況
3.好處是服務(wù)與服務(wù)注冊(cè)中心之間解耦,缺點(diǎn)是除非部署環(huán)境內(nèi)置,否則同樣需要引入這樣一個(gè)高可用系統(tǒng)組件,并進(jìn)行設(shè)置和管理
五、事件驅(qū)動(dòng)數(shù)據(jù)管理
A.微服務(wù)和分布式數(shù)據(jù)管理問(wèn)題
1.使用關(guān)系型數(shù)據(jù)庫(kù)的一個(gè)主要優(yōu)點(diǎn)是應(yīng)用程序可以使用ACID事務(wù),另一大好處是它提供了SQL語(yǔ)言
2.每個(gè)微服務(wù)所擁有的數(shù)據(jù)對(duì)當(dāng)前微服務(wù)來(lái)說(shuō)是私有的,只能通過(guò)其提供的API進(jìn)行訪問(wèn)
3.一個(gè)分區(qū)的數(shù)據(jù)存儲(chǔ)混合持久化架構(gòu)具有許多優(yōu)點(diǎn),包括了松耦合的服務(wù)以及更好的性能與可擴(kuò)展性
B.事件驅(qū)動(dòng)架構(gòu)
1.微服務(wù)在發(fā)生某些重要事件時(shí)發(fā)布一個(gè)事件,其他微服務(wù)訂閱了這些事件,當(dāng)微服務(wù)接收到一個(gè)事件時(shí),它可以更新自己的業(yè)務(wù)實(shí)體
2.可以使用事件實(shí)現(xiàn)跨多服務(wù)的業(yè)務(wù)事務(wù)
3.優(yōu)點(diǎn):能夠?qū)崿F(xiàn)跨越多服務(wù)并提供最終一致性事務(wù),使得應(yīng)用程序能夠維護(hù)物化視圖
4.缺點(diǎn):其編程模型比使用ACID事務(wù)更復(fù)雜,訂閱者必須要檢測(cè)和忽略重復(fù)的事件
C.實(shí)現(xiàn)原子性
1.標(biāo)準(zhǔn)方法是使用涉及到數(shù)據(jù)庫(kù)和Message Broker的分布式事務(wù)
D.使用本地事務(wù)發(fā)布事件
1.應(yīng)用程序使用僅涉及本地事務(wù)的多步驟過(guò)程來(lái)發(fā)布事件,訣竅在于存儲(chǔ)業(yè)務(wù)實(shí)體狀態(tài)的數(shù)據(jù)庫(kù)中有一個(gè)用作消息隊(duì)列的EVENT表

2.好處是保證了被發(fā)布的事件每次更新都不依賴于2PC,事件可以消除推斷的需要
3.缺點(diǎn)是很容易出錯(cuò)
E.挖掘數(shù)據(jù)庫(kù)事務(wù)日志
1.使用線程或進(jìn)程發(fā)布事件,該進(jìn)程或線程對(duì)數(shù)據(jù)庫(kù)的事務(wù)或者提交日志進(jìn)行挖掘,當(dāng)更新數(shù)據(jù)庫(kù)時(shí),更改信息被記錄到數(shù)據(jù)庫(kù)的事務(wù)日志中,Transaction Log Miner線程或進(jìn)程讀取事務(wù)日志并向Message Broker發(fā)布事件

2.好處是它能保證被發(fā)布的事件每次更新都不依賴于2PC,可以通過(guò)將事件發(fā)布與應(yīng)用程序的業(yè)務(wù)邏輯分離來(lái)簡(jiǎn)化應(yīng)用程序
3.缺點(diǎn)是事務(wù)日志的格式對(duì)于每個(gè)數(shù)據(jù)庫(kù)來(lái)說(shuō)都是專(zhuān)有的,記錄于事務(wù)日志中的低級(jí)別更新可能難以對(duì)高級(jí)業(yè)務(wù)事件進(jìn)行逆向工程
F.使用事件溯源
1.事件溯源通過(guò)使用完全不同的、不間斷的方式來(lái)持久化業(yè)務(wù)實(shí)體,實(shí)現(xiàn)無(wú)2PC原子性。應(yīng)用程序不存儲(chǔ)實(shí)體的當(dāng)前狀態(tài),而是存儲(chǔ)一系列狀態(tài)改變事件。通過(guò)無(wú)回放事件來(lái)重建實(shí)體當(dāng)前狀態(tài)。由于保存事件是一個(gè)單一操作,因此具有原子性
2.事件被持久化在事件存儲(chǔ)中,事件存儲(chǔ)是一個(gè)事件數(shù)據(jù)庫(kù),該存儲(chǔ)有一個(gè)用于添加和檢索實(shí)體事件的API
3.好處:可以在狀態(tài)發(fā)生變化時(shí)可靠地發(fā)布事件,解決了數(shù)據(jù)一致性;持久化的是事件而不是領(lǐng)域?qū)ο?,避免了?duì)象關(guān)系阻抗失配問(wèn)題;提供對(duì)業(yè)務(wù)實(shí)體所做更改的100%可靠的審計(jì)日志;業(yè)務(wù)邏輯包括松耦合的交換事件業(yè)務(wù)實(shí)體,從單體應(yīng)用程序遷移到微服務(wù)架構(gòu)更加容易
4.缺點(diǎn):是一種不同而陌生的編程風(fēng)格,存在學(xué)習(xí)曲線;事件存儲(chǔ)僅支持通過(guò)主鍵查找業(yè)務(wù)實(shí)體;必須使用命令查詢責(zé)任分離(CQRS)來(lái)實(shí)現(xiàn)查詢,應(yīng)用程序必須處理最終一致的數(shù)據(jù)
六、選擇部署策略
A.動(dòng)機(jī)
1.微服務(wù)應(yīng)用程序由數(shù)十甚至上百個(gè)服務(wù)組成,服務(wù)以不同的語(yǔ)言和框架編寫(xiě),每個(gè)都是一個(gè)迷你的應(yīng)用程序,需要根據(jù)該服務(wù)的需求運(yùn)行每個(gè)服務(wù)的一定數(shù)量的實(shí)例,必須為每個(gè)服務(wù)實(shí)例提供相應(yīng)的CPU、內(nèi)存和I/O資源
B.單主機(jī)多服務(wù)實(shí)例模式
1.單主機(jī)多服務(wù)實(shí)例(Multiple Service Instances per Host)模式,可以提供一個(gè)或多個(gè)物理主機(jī)或虛擬主機(jī),并在每個(gè)上運(yùn)行多個(gè)服務(wù)實(shí)例,每個(gè)服務(wù)實(shí)例在一個(gè)或多個(gè)主機(jī)的標(biāo)準(zhǔn)端口上運(yùn)行
2.一種變體是每個(gè)服務(wù)實(shí)例都是一個(gè)進(jìn)程或進(jìn)程組
3.另一個(gè)變體是在同一進(jìn)程或進(jìn)程組中運(yùn)行多個(gè)服務(wù)實(shí)例
4.優(yōu)點(diǎn):資源使用率相對(duì)較高,多個(gè)服務(wù)實(shí)例共享服務(wù)器及其操作系統(tǒng)。如果進(jìn)程或進(jìn)程組運(yùn)行了多個(gè)服務(wù)實(shí)例,則效率更高;部署服務(wù)實(shí)例相對(duì)較快;由于缺乏開(kāi)銷(xiāo),通常啟動(dòng)一個(gè)服務(wù)是非常快的
5.缺點(diǎn):服務(wù)實(shí)例很少或者沒(méi)有隔離,除非每個(gè)服務(wù)實(shí)例是一個(gè)單獨(dú)的進(jìn)程,一個(gè)行為不當(dāng)?shù)姆?wù)實(shí)例可能會(huì)占用掉主機(jī)的所有內(nèi)存或CPU;部署服務(wù)的運(yùn)維團(tuán)隊(duì)必須了解執(zhí)行此操作的具體細(xì)節(jié)
C.每個(gè)主機(jī)一個(gè)服務(wù)實(shí)例模式
1.每個(gè)主機(jī)一個(gè)服務(wù)實(shí)例(Service Instance per Host)模式,在主機(jī)上單獨(dú)運(yùn)行每個(gè)服務(wù)實(shí)例,每個(gè)虛擬機(jī)一個(gè)服務(wù)實(shí)例模式和每個(gè)容器一個(gè)服務(wù)實(shí)例模式
2.每個(gè)虛擬機(jī)一個(gè)服務(wù)實(shí)例模式,將每個(gè)服務(wù)打包為一個(gè)虛擬機(jī)(VM)鏡像,每個(gè)服務(wù)實(shí)例都是一個(gè)使用該VM鏡像啟動(dòng)的VM

3.每個(gè)虛擬機(jī)一個(gè)服務(wù)實(shí)例模式的優(yōu)點(diǎn):每個(gè)服務(wù)實(shí)例運(yùn)行是完全隔離的;可以利用成熟的云基礎(chǔ)架構(gòu);封裝了服務(wù)的實(shí)現(xiàn)技術(shù);
4.每個(gè)虛擬機(jī)一個(gè)服務(wù)實(shí)例模式的缺點(diǎn):資源利用率較低;公共IaaS中的VM通常是收費(fèi)的,無(wú)論他們是處于繁忙還是空閑;部署新版本的服務(wù)時(shí)通常很慢;要對(duì)很多未劃分的重?fù)?dān)負(fù)責(zé);
5.每個(gè)容器一個(gè)服務(wù)實(shí)例(Service Instance per Container)模式,每個(gè)服務(wù)實(shí)例都在其自己的容器中運(yùn)行(Docker)

6.容器模式的優(yōu)點(diǎn):將服務(wù)實(shí)例彼此隔離,輕松監(jiān)控每個(gè)容器所消耗的資源,封裝了服務(wù)實(shí)現(xiàn)技術(shù),容器管理API作為管理服務(wù)的API;容器是輕量級(jí)技術(shù),可以快速構(gòu)建,也可以很快地啟動(dòng);
7.容器模式的缺點(diǎn):不成熟,不像VM那樣安全,因?yàn)楣蚕砹酥鳈C(jī)的OS內(nèi)核;需要負(fù)責(zé)劃分容器鏡像管理重?fù)?dān);通常部署在一個(gè)按單個(gè)VM收費(fèi)的基礎(chǔ)設(shè)施上,可能會(huì)產(chǎn)生超額配置VM的額外成本,以處理負(fù)載峰值;
D.Serverless部署
1.AWS Lambda
七、重構(gòu)單體為微服務(wù)
A.微服務(wù)重構(gòu)概述
1.一個(gè)不要使用的策略是“大爆炸”重寫(xiě),就是您將所有的開(kāi)發(fā)工作都集中在從頭開(kāi)始構(gòu)建新的基于微服務(wù)的應(yīng)用程序
2.應(yīng)該逐步重構(gòu)單體應(yīng)用程序,逐漸添加新功能,并以微服務(wù)的形式創(chuàng)建現(xiàn)有功能的擴(kuò)展——以互補(bǔ)的形式修改單體應(yīng)用,并且一同運(yùn)行微服務(wù)和修改后的單體
B.策略一:停止挖掘
1.洞穴定律:當(dāng)你身處在一個(gè)洞穴中,你應(yīng)該停止挖掘
2.當(dāng)你的單體應(yīng)用變得難以管理時(shí),應(yīng)該停止擴(kuò)張,避免使單體變得更大
3.三種策略來(lái)訪問(wèn)單體數(shù)據(jù):
* 調(diào)用由單體提供的遠(yuǎn)程API
* 直接訪問(wèn)單體數(shù)據(jù)庫(kù)
* 維護(hù)自己的數(shù)據(jù)副本,與單體數(shù)據(jù)庫(kù)同步
4.粘合代碼,將服務(wù)與單體集成,位于單體、服務(wù)或兩者中的粘合代碼負(fù)責(zé)數(shù)據(jù)集成,有時(shí)被稱(chēng)為防護(hù)層(anti-corruption layer),因?yàn)檎澈洗a阻止了服務(wù)被遺留的單體領(lǐng)域模型的概念污染,這些服務(wù)具有自己的原始領(lǐng)域模式
C.策略二:前后端分離
1.縮小單體應(yīng)用的一個(gè)策略是從業(yè)務(wù)邏輯層和數(shù)據(jù)訪問(wèn)層拆分出表現(xiàn)層:
* 表現(xiàn)層(Presentation Layer,PL)處理HTTP請(qǐng)求并實(shí)現(xiàn)(REST) API或基于HTML的WebUI組件,通常存在大量代碼
* 業(yè)務(wù)邏輯層(Business Logic Layer,BLL)作為應(yīng)用程序核心,實(shí)現(xiàn)業(yè)務(wù)規(guī)則的組件
* 數(shù)據(jù)訪問(wèn)層(Data Access Layer,DAL)訪問(wèn)基礎(chǔ)架構(gòu)組件的組件,如數(shù)據(jù)庫(kù)和消息代理
2.業(yè)務(wù)層具有由一個(gè)或多個(gè)門(mén)面組成的粗粒度API,其封裝了業(yè)務(wù)邏輯組件。一個(gè)應(yīng)用程序包含表現(xiàn)層,另一個(gè)應(yīng)用程序包含業(yè)務(wù)和數(shù)據(jù)訪問(wèn)邏輯
3.優(yōu)點(diǎn):使您能夠獨(dú)立于彼此開(kāi)發(fā)、部署和擴(kuò)展這兩個(gè)應(yīng)用,允許表現(xiàn)層開(kāi)發(fā)人員在用戶界面上快速迭代,可以輕松執(zhí)行A/B測(cè)試;暴露了可以被您開(kāi)發(fā)的微服務(wù)調(diào)用的遠(yuǎn)程API
4.只是一個(gè)局部解決方案,兩個(gè)應(yīng)該程序中的一個(gè)或兩個(gè)很可能是一個(gè)無(wú)法管理的單體,需要使用第三種策略來(lái)消除剩余的整體或單體
D.策略三:提取服務(wù)
1.將龐大的現(xiàn)有模塊轉(zhuǎn)變?yōu)楠?dú)立的微服務(wù),每次提取一個(gè)模塊并將其轉(zhuǎn)換成服務(wù)時(shí),單體就會(huì)縮小
2.從容易提取的幾個(gè)模塊開(kāi)始,將得到微服務(wù)的相關(guān)經(jīng)驗(yàn),之后提取能給你最大利益的模塊;提取頻繁更改的模塊通常是有益的;提取與單體的其他模塊有顯著不同的模塊也是有益的;
3.提取模塊第一步是在模塊和單體之間定義一個(gè)粗粒度接口;一旦實(shí)現(xiàn)了粗粒度接口,就可以將模塊變成獨(dú)立的服務(wù),必須編寫(xiě)代碼以使單體和服務(wù)通過(guò)使用進(jìn)程間通信(IPC)機(jī)制的API進(jìn)行通信;第二個(gè)重構(gòu)步驟是將模塊轉(zhuǎn)換為一個(gè)獨(dú)立服務(wù);
https://pan.baidu.com/s/1o9i6Ats
ee16