微服務(wù)架構(gòu)設(shè)計模式 | 第3章 微服務(wù)架構(gòu)中的進(jìn)程間通信

前言

這是一本關(guān)于微服務(wù)架構(gòu)設(shè)計方面的書,這是本人閱讀的學(xué)習(xí)筆記。首先對一些符號做些說明:

()為補(bǔ)充,一般是書本里的內(nèi)容;
[]符號為筆者筆注;

微服務(wù)架構(gòu)將應(yīng)用程序構(gòu)建為一組服務(wù),這些服務(wù)必須經(jīng)常協(xié)作才能處理各種外部請求。而服務(wù)的實例通常是在多臺機(jī)器上運(yùn)行的進(jìn)程,所以它們必須使用進(jìn)程間通信進(jìn)行交互。

當(dāng)前有多種進(jìn)程間通信機(jī)制,比較流行的是REST(使用JSON)。選擇合適的進(jìn)程間通信機(jī)制是一個重要的架構(gòu)決策,它影響應(yīng)用程序的可用性。


1. 微服務(wù)架構(gòu)中的進(jìn)程間通信概述

進(jìn)程間通信技術(shù)有:基于同步請求/響應(yīng)、異步的基于消息的通信機(jī)制等。

1.1 交互方式的兩個維度

  • 第一個維度
    • 一對一:每個客戶端請求由一個服務(wù)實例來處理;
    • 一對多:每個客戶端請求由多個服務(wù)實例來處理;
  • 第二個維度
    • 同步模式:客戶端請求需要服務(wù)端實時響應(yīng),客戶端等待響應(yīng)時可能導(dǎo)致堵塞;
    • 異步模式:客戶端請求不會阻塞進(jìn)程,服務(wù)端的響應(yīng)可以是非實時的;
交互方式的兩個維度

1.2 交互方式的類型

  • 一對一交互
    • 請求/響應(yīng):一個客戶端向服務(wù)端發(fā)起請求,等待響應(yīng);客戶端期望服務(wù)端很快就會發(fā)送響應(yīng)。在一個基于線程的應(yīng)用中,等待過程可能造成線程阻塞。這樣的方式會導(dǎo)致服務(wù)的緊耦合;
    • 異步請求/響應(yīng):客戶端發(fā)送請求到服務(wù)端,服務(wù)端異步響應(yīng)請求。客戶端在等待時不會阻塞線程,因為服務(wù)端響應(yīng)不會馬上返回;
    • 單向通知:客戶端的請求發(fā)送到服務(wù)端,但是并不期望服務(wù)端做出任何響應(yīng);
  • 一對多交互
    • 發(fā)布/訂閱方式:客戶端發(fā)布通知消息,被零個或多個感興趣的服務(wù)訂閱;
    • 發(fā)布/異步響應(yīng)方式:客戶端發(fā)布請求消息,然后等待從感興趣的服務(wù)發(fā)回的響應(yīng);

1.3 API的演化

  • 語義化版本控制:用于指定如何使用版本號,并且以正確的方式遞增版本。其由3部分組成:
    • MAJOR:對API進(jìn)行不兼容的修改時;
    • MINOR:對API進(jìn)行向后兼容的增強(qiáng)時;
    • PATCH:進(jìn)行向后兼容的錯誤修復(fù)時;
    • 規(guī)范:MAJOR.MINOR.PATCH;
  • 進(jìn)行次要并且向后兼容的改變:對ADP的附加修改更換或功能增強(qiáng)。其包括:
    • 添加可選屬性
    • 向響應(yīng)添加屬性;
    • 添加新操作;
  • 進(jìn)行主要并且不向后兼容的版本:需要服務(wù)在一段時間內(nèi)同時支持新舊版本的API時;

1.4 消息的格式

消息格式會影響進(jìn)程間通信的效率、API的可用性和可演化新。使用跨語言的消息格式尤為重要;

  • 基于文本的消息格式
    • 舉例:JSON、XML;
    • 好處:可讀性高、自描述性,有良好的向后兼容性 [消息接收方只需挑選他們感興趣的值,忽略其他];
    • 弊端:信息冗長,解析文本需要額外的性能效率開銷;
  • 二進(jìn)制消息格式
    • 舉例:Tars、Protocol Buffers、Avro;
    • 好處:提供強(qiáng)類型定義的IDL(接口描述文件),用于定義消息;編譯器會根據(jù)這些格式生成序列化和反序列化代碼;
    • 弊端:不得不采用API優(yōu)先的方法進(jìn)行服務(wù)設(shè)計


2. 基于同步遠(yuǎn)程過程調(diào)用模式的通信

2.1 遠(yuǎn)程過程調(diào)用RPI

指客戶端使用同步的遠(yuǎn)程過程調(diào)用協(xié)議(如REST)來調(diào)用服務(wù)。

遠(yuǎn)程過程調(diào)用工作原理

圖解:客戶端業(yè)務(wù)邏輯調(diào)用代理接口,這個接口由遠(yuǎn)程過程調(diào)用代理適配器類實現(xiàn)。遠(yuǎn)程過程調(diào)用代理向服務(wù)器發(fā)送請求,該請求由遠(yuǎn)程過程調(diào)用服務(wù)器適配器類處理,該類通過接口調(diào)用服務(wù)的業(yè)務(wù)邏輯。然后它將恢復(fù)發(fā)送回遠(yuǎn)程過程調(diào)用代理,該代理將結(jié)果返回給客戶端的業(yè)務(wù)邏輯。

  • 代理接口:通常是封裝底層通信協(xié)議,如下面介紹的REST與gRPC。

2.2 REST通信協(xié)議的特點(diǎn)及優(yōu)缺點(diǎn)

REST是一種(總是)使用HTTP協(xié)議的進(jìn)程間通信機(jī)制。

特點(diǎn)

  • REST使用HTTP動詞來操作資源,使用URL引用這些資源;
  • 資源通常使用XML文檔或JSON對象的形式,也可以使用其他格式(二進(jìn)制等);
  • REST的成熟模型有:有4個層次(P71);
  • REST API:最流行的REST IDL是Open API規(guī)范,它是從Swagger開源項目發(fā)展而來的;
  • REST API的挑戰(zhàn)
    • 在一個請求中獲取多個資源的挑戰(zhàn):指如何在單個請求中檢索多個相關(guān)對象;
    • 吧操作映射為HTTP動詞的挑戰(zhàn):指一個HTTP動詞可能對應(yīng)多種方法,如PUT請求更新訂單可能包括取消訂單、修改訂單等;

好處

  • 非常簡單,大家比較熟悉;
  • 可以使用瀏覽器擴(kuò)展(如Postman插件)或者curl之類的命令行測試HTTP API;
  • 直接支持請求/響應(yīng)方式的通信;
  • HTTP對防火墻友好;
  • 不需要中間代理,簡化系統(tǒng)架構(gòu);

弊端

  • 只支持請求/響應(yīng)方式的通信;
  • 可能導(dǎo)致可用性降低。由于客戶端和服務(wù)直接通信而沒有代理來緩沖消息,因此它們必須在REST API調(diào)用期間保持在線;
  • 客戶端必須知道服務(wù)實例的位置(URL)??蛻舳吮仨毷褂盟^的服務(wù)發(fā)現(xiàn)機(jī)制來定位服務(wù)實例;
  • 在單個請求中獲取多個資源具有挑戰(zhàn)性;
  • 有時很難將多個更新操作映射到HTTP動詞;

2.3 gRPC通信協(xié)議的特點(diǎn)及優(yōu)缺點(diǎn)

gRPC是一個用于編寫跨語言客戶端和服務(wù)端的框架,是一種二進(jìn)制協(xié)議。

特點(diǎn)

  • gRPC API由一個或多個服務(wù)和請求/響應(yīng)消息定義組成;
  • 服務(wù)定義類似Java接口,是強(qiáng)類型方法的集合;
  • 使用Protocol Buffers作為消息格式,是一種高效且緊湊的二進(jìn)制格式,是一種標(biāo)記格式;
    • 因此gRPC使API能夠在保持向后兼容的同時進(jìn)行變更;

好處

  • 設(shè)計具有復(fù)雜更新操作的API非常簡單;
  • 具有高效、緊湊的進(jìn)程間通信機(jī)制,尤其是在交換大量消息時;
  • 支持在遠(yuǎn)程過程調(diào)用和消息傳遞過程中使用雙向流式消息方式;
  • 實現(xiàn)了客戶端和用各種語言編寫的服務(wù)端之間的互操作性;

弊端

  • 與基于REST/JSON的API機(jī)制相比,JavaScript客戶端使用基于gRPC的API需要做更多的工作;
  • 舊式防火墻可能不支持HTTP/2;

2.4 同步通信下的局部故障風(fēng)險

客戶端和服務(wù)端是獨(dú)立的進(jìn)程,服務(wù)端很可能無法在有限的時間內(nèi)對客戶端的請求作出響應(yīng)。

同步通信下的局部故障風(fēng)險

圖解:當(dāng)Order Service無響應(yīng)時,OrderServiceProxy將無限期地阻塞,等待響應(yīng)。會消耗時間、浪費(fèi)線程等資源。最終API Gateway將資源消耗,無法處理請求,整個API不可用。

解決方法是

  • 必須讓遠(yuǎn)程過程調(diào)用代理(如OrderServiceProxy)有正確處理無響應(yīng)服務(wù)的能力;
  • 需要決定如何從失敗的遠(yuǎn)程服務(wù)中恢復(fù);

2.5 解決局部故障的思路與方法

  • 開發(fā)可靠地遠(yuǎn)程過程調(diào)用代理:使用Netflix描述的方法,可以包括以下機(jī)制的組合;
    • 網(wǎng)絡(luò)超時:在等待針對請求的響應(yīng)時,不要做成無限阻塞,而是設(shè)定一個超時,用來保證不會一直在無響應(yīng)的請求上浪費(fèi)資源;
    • 限制客戶端向服務(wù)器發(fā)出請求的數(shù)量:把客戶端能夠向特定服務(wù)發(fā)起的請求設(shè)置一個上限,如果請求達(dá)到上限,就讓請求立刻失??;
    • 斷路器模式:監(jiān)控客戶端發(fā)出請求的成功和失敗數(shù)量,如果失敗的比例超過一定的閾值,就啟動斷路器,讓后續(xù)調(diào)用立即失敗。如果大量請求都以失敗告終,說明被調(diào)服務(wù)不可用。經(jīng)過一定時間后,客戶端繼續(xù)嘗試,如果調(diào)用成功,則移除斷路器;
  • 從服務(wù)失效故障中恢復(fù)
    • 可以只是服務(wù)向其客戶端返回錯誤;
    • 返回備用值(如默認(rèn)值或緩存響應(yīng));

2.6 應(yīng)用層服務(wù)發(fā)現(xiàn)模式

服務(wù)及其客戶直接與服務(wù)注冊表交互;

應(yīng)用層服務(wù)發(fā)現(xiàn)模式工作原理
  • 服務(wù)實例使用服務(wù)注冊表注冊其網(wǎng)絡(luò)位置??蛻舳耸紫韧ㄟ^查詢服務(wù)注冊表獲取服務(wù)實例列表來調(diào)用服務(wù),然后它向其中一個實例發(fā)送請求;
  • 這種服務(wù)發(fā)現(xiàn)是以下兩種模式的組合:
    • 自注冊模式:服務(wù)實例向服務(wù)注冊表注冊自己;
      • 可以提供運(yùn)行狀態(tài)檢查URL(“心跳”功能,服務(wù)注冊表定期調(diào)用該端點(diǎn)驗證服務(wù)實例是否正常且可用于處理請求);
    • 客戶端發(fā)現(xiàn)模式:客戶端從服務(wù)注冊表檢索可用服務(wù)實例的列表,并在它們之間進(jìn)行負(fù)載均衡;
      • 為了提高性能,客戶端可能會緩存服務(wù)實例;
  • 業(yè)界有Netflix開發(fā)的Eureka組件,一個高可用的服務(wù)注冊表;Pivotal開發(fā)的SpringCloud
    使相關(guān)組件使用非常簡單;

2.7 平臺層服務(wù)發(fā)現(xiàn)模式

通過部署基礎(chǔ)設(shè)施來處理服務(wù)發(fā)現(xiàn);

平臺層服務(wù)發(fā)現(xiàn)模式工作原理
  • 部署平臺包括一個服務(wù)注冊表,用于跟蹤已部署服務(wù)的IP地址;
  • 部署平臺為每個服務(wù)提供DNS名稱、虛擬IP(VIP)地址和解析為VIP地址的DNS名稱;
  • 這種服務(wù)發(fā)現(xiàn)是以下兩種模式的組合:
    • 第三方注冊模式:由第三方負(fù)責(zé)(稱為注冊服務(wù)器)處理注冊,而不是服務(wù)本身先服務(wù)注冊表注冊自己;
    • 服務(wù)端發(fā)現(xiàn)模式:客戶端向DNS名稱發(fā)出請求,對該DNS名稱的請求被解析到路由器,路由器查詢服務(wù)注冊表并對請求進(jìn)行負(fù)載均衡;
  • 業(yè)界有Docker與Kubernetes,都內(nèi)置有服務(wù)注冊表與服務(wù)發(fā)現(xiàn)機(jī)制;


3. 基于異步消息模式的通信

使用消息機(jī)制時,服務(wù)之間的通信采用異步交換消息的方式完成。

基于消息機(jī)制的應(yīng)用程序通常采用消息代理;另一種選擇是使用無代理架構(gòu)。

3.1 關(guān)于消息

消息由消息頭部和消息主體組成;

  • 消息頭部
    • 標(biāo)題:名稱與值對;
    • 消息ID:消息傳遞基礎(chǔ)唯一ID;
    • 返回地址:指定發(fā)送回復(fù)的消息通道;
  • 消息主體:以文本或二進(jìn)制格式發(fā)送的數(shù)據(jù);
    • 文檔:包含數(shù)據(jù)的通用消息。接受者決定如何解釋它。對命令式消息的回復(fù)是文檔消息的一種應(yīng)用場景;
    • 命令:一條等同于RPC請求的消息。它指定要調(diào)用的操作及其參數(shù);
    • 事件:表示發(fā)送方這一端發(fā)生了重要的事件。事件通常是領(lǐng)域事件,表示領(lǐng)域?qū)ο蟮臓顟B(tài)更改;

3.2 關(guān)于消息通道

消息通道工作原理

有以下兩種類型的消息通道:

  • 點(diǎn)對點(diǎn)通道
    • 向正在從通道讀取的一個消費(fèi)者傳遞消息;
    • 如:命令式消息通常通過點(diǎn)對點(diǎn)通道發(fā)送;
  • 發(fā)布 - 訂閱通道
    • 將一條消息發(fā)送給所有訂閱的接收方;
    • 如:事件式消息通常通過發(fā)布 - 訂閱通道發(fā)送;

3.3 使用消息機(jī)制實現(xiàn)交互方式

介紹下面四種交互方式的消息機(jī)制:

  • 實現(xiàn)單向通知
    • 客戶端將消息(通常是命令式消息)發(fā)送到服務(wù)所擁有的點(diǎn)對點(diǎn)通道;
    • 服務(wù)訂閱該通道并處理該消息,但服務(wù)不會發(fā)回回復(fù);
  • 實現(xiàn)發(fā)布/訂閱
    • 客戶端將消息發(fā)布到由多個接收方讀取的發(fā)布/訂閱通道;
    • 發(fā)布領(lǐng)域事件的服務(wù)擁有自己的發(fā)布/訂閱通道,通道名稱往往派生自領(lǐng)域類;
    • 如:Order Service將Order事件發(fā)布到Order通道;Delivery Service將Delivery事件發(fā)布到Delivery通道;
  • 實現(xiàn)發(fā)布/異步響應(yīng)
    • 一種更高級的交互方式,將發(fā)布/訂閱與請求/響應(yīng)這兩種方式的元素組合實現(xiàn);
    • 客戶端發(fā)布一條消息,在消息的頭部中指定回復(fù)通道。這個通道同時也是一個發(fā)布 - 訂閱通道;
    • 消費(fèi)者將包含相關(guān)性ID的回復(fù)消息寫入回復(fù)通道;
    • 客戶端通過使用相關(guān)性ID來收集響應(yīng),以此將回復(fù)消息與請求進(jìn)行匹配;
  • 實現(xiàn)請求/響應(yīng)和異步請求/響應(yīng)
    • 客戶端發(fā)送請求,服務(wù)會發(fā)回回復(fù);
    • 客戶端必須告知服務(wù)發(fā)送回復(fù)消息的位置,并且必須將回復(fù)消息與請求匹配;
      • 即:客戶端發(fā)送具有回復(fù)通道頭部的命令式消息。服務(wù)器將回復(fù)消息寫入回復(fù)通道,該回復(fù)消息包含與消息標(biāo)識符具有相同的相關(guān)性ID。客戶端使用相關(guān)性ID將回復(fù)消息與請求匹配;
    • 由于客戶端和服務(wù)端使用消息機(jī)制進(jìn)行通信,因此交互本質(zhì)上是異步的;
    • 工作原理圖如下:
實現(xiàn)請求/響應(yīng)交互方式工作原理圖

3.4 為基于消息機(jī)制的服務(wù)API創(chuàng)建API規(guī)范

服務(wù)的異步API規(guī)范必須制定消息通道的名稱、通過每個通道交換的消息類型及其格式。

服務(wù)的異步API
  • 服務(wù)的異步API包含供客戶端調(diào)用的操作和由服務(wù)對外發(fā)布的事件;
  • (記錄異步操作)可以使用以下兩種不同交互方式之一調(diào)用服務(wù)的操作:
    • 請求/異步響應(yīng)式API:包括服務(wù)端命令消息通道、服務(wù)接受的命令式消息的具體類型和格式,以及服務(wù)發(fā)送的回復(fù)消息的類型和格式;
    • 單向通知式API:包括服務(wù)的命令消息通道,以及服務(wù)接受的命令式消息的具體類型和格式;
  • (記錄事件發(fā)布)服務(wù)還可以使用發(fā)布/訂閱的方式對外發(fā)布事件;
    • 此API風(fēng)格等規(guī)范包括事件通道以及服務(wù)發(fā)布到通道的事件式消息的類型和格式;

3.5 無代理消息的利弊

在無代理的架構(gòu)中,服務(wù)可以直接交換信息。

好處

  • 允許更輕的網(wǎng)絡(luò)流量和更低的延遲,因為沒有中間代理過程;
  • 消除了消息代理可能成為性能瓶頸或單點(diǎn)故障的可能性;
  • 具有較低的操作復(fù)雜性,因為不需要設(shè)置和維護(hù)消息代理;

弊端

  • 服務(wù)需要了解彼此位置,因此必須使用服務(wù)發(fā)現(xiàn)機(jī)制;
  • 降低可用性,因為在交換消息時,信息的接收方和發(fā)送方必須同時在線;
  • 在實現(xiàn)例如確保消息能夠成功投遞這些復(fù)雜功能時的挑戰(zhàn)性更大;

舉例

  • ZeroMQ:一種流行的無代理消息技術(shù);


無代理與基于代理的架構(gòu)


3.6 基于代理消息的利弊

消息代理是所有消息的中介節(jié)點(diǎn);發(fā)送方將消息寫入消息代理,消息代理將消息發(fā)送給接收方。

好處

  • 松耦合;
  • 消息緩存:消息代理可以在消息被處理之前一直緩存消息;
  • 靈活的通信:消息代理支持前面提到的所有交互方式;
  • 明確的進(jìn)程間通信

弊端

  • 潛在的性能瓶頸:解決方法 - 橫向擴(kuò)展;
  • 潛在的單點(diǎn)故障:解決辦法 - 大多數(shù)現(xiàn)代消息代理是高可用的;
  • 額外的操作復(fù)雜性:消息系統(tǒng)必須是一個獨(dú)立安裝、配置和運(yùn)維的系統(tǒng)組件;

舉例

  • 流行的開源消息代理:Apache ActiveMQ(JMS)、RabbitMQ(AMQP)、Apache Kafka;
  • 基于云的消息服務(wù):AWS Kinesis、AWS SQS;
  • 上述除了AWS SQS外都支持點(diǎn)對點(diǎn)和發(fā)布 - 訂閱通道;AWS SQS只支持點(diǎn)對點(diǎn)通道;

每個消息代理都有自己的特色


3.7 選擇消息代理需要考慮的因素

  • 支持的編程語言;
  • 支持的信息標(biāo)準(zhǔn)
  • 消息排序:消息代理是否能夠保留消息的排序;
  • 投遞保證:消息代理提供怎樣的消息投遞保證;
  • 持久性;
  • 耐久性:如果接收方重新連接到消息代理,它是否會收到斷開連接時發(fā)送的消息;
  • 可擴(kuò)展性
  • 延遲;
  • 競爭性(并發(fā))接收方:消息代理是否支持競爭性接收方;

3.8 處理并發(fā)和消息順序

問題描述:在橫向擴(kuò)展多個消息接收方的實例的情況下,消息的順序可能會錯位。

解決方法:使用分片消息通道擴(kuò)展接收方;

使用分片消息通道擴(kuò)展接收方工作原理圖

圖解

  • 分片通道由兩個或多個分片組成,每個分片的行為類似于一個通道;
  • 發(fā)送方在消息頭部指定分片鍵,通常是任意字符串或字節(jié)序列。消息代理使用分片鍵將消息分配給特定的分片;
    • 如:通過計算分片鍵的散列來選擇分片;
  • 消息代理將接收方的多個實例組合在一起,并將他們視為相同的邏輯接收方;
    • 如:Apache Kafka使用術(shù)語消費(fèi)者組;消息代理將每個分片分配給單個接收器;它在接收方啟動和關(guān)閉時重新分配分片;

3.9 處理重復(fù)消息

問題描述:客戶端、網(wǎng)絡(luò)或消息代理的故障可能導(dǎo)致消息被多次傳遞。

有以下兩種解決辦法:

  • 編寫冪等消息處理器
    • 冪等操作特點(diǎn):任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同;
  • 跟蹤消息并丟棄重復(fù)消息
    • 將消息處理程序注冊進(jìn)應(yīng)用程序表(NoSQL)【第七章介紹】;
    • 使用message id跟蹤消息并丟棄重復(fù)消息,如下圖:
使用message id跟蹤消息并丟棄重復(fù)消息

3.10 事務(wù)性消息

  • 使用數(shù)據(jù)庫表作為消息隊列
    • 事務(wù)性發(fā)件箱:通過將事件或消息保存在數(shù)據(jù)庫OUTBOX表中,將其作為數(shù)據(jù)庫事務(wù)是一部分發(fā)布;
      使用數(shù)據(jù)庫表作為消息隊列
  • 通過輪詢模式發(fā)布事件
    • 輪詢發(fā)布數(shù)據(jù):通過輪詢數(shù)據(jù)庫中的發(fā)件箱發(fā)布消息;
    • 小規(guī)模下運(yùn)行良好,弊端在于經(jīng)常輪詢數(shù)據(jù)庫會造成較大開銷;
  • 使用事務(wù)日志拖尾模式發(fā)布事件
    • 事務(wù)日志拖尾:通過拖尾數(shù)據(jù)日志發(fā)布對數(shù)據(jù)庫所做的修改;
    • 一些行業(yè)案例:Debezium、Linkedln Databus、DynamoDB streams、Eventuate Tram;
    • 下圖解:每次應(yīng)用程序提交到數(shù)據(jù)庫的更新都對應(yīng)著數(shù)據(jù)庫事務(wù)日志中的一個條目;事務(wù)日志挖掘器可以讀取事務(wù)日志,把每條跟消息有關(guān)的記錄發(fā)送給消息代理;
事務(wù)日志拖尾模式


3.11 消息相關(guān)的類庫和框架

服務(wù)需要使用庫來發(fā)送和接收消息。

有兩種方法:

  • 使用消息代理的客戶端庫,問題有:
    • 客戶端庫將發(fā)布消息的業(yè)務(wù)邏輯耦合到消息代理API;
    • 客戶端庫通常只提供發(fā)送和接收消息的基本機(jī)制,不支持更高級別的交互方式;
    • 消息代理的客戶端庫通常非常底層,需要多行代碼才能發(fā)送/接收消息;
  • 使用更高級別的庫或框架來隱藏底層細(xì)節(jié),并直接支持更高級別的交互方式
  • 如Eventuate Tram框架;


4. 使用異步消息提高可用性

采用同步通信機(jī)制處理請求,會對系統(tǒng)的可用性帶來影響。因此,應(yīng)盡可能選擇異步通信機(jī)制來處理服務(wù)之間的調(diào)用。

4.1 同步消息會降低可用性

同步交互方式提交訂單流程圖


4.2 消除同步交互的方法

  • 使用異步交互模式
    • 下圖解:客戶的通過Order Service發(fā)送一個請求消息交換消息的方式創(chuàng)建訂單;這個服務(wù)隨即采用異步交換消息的方式跟其他服務(wù)通信完成訂單的創(chuàng)建;
    • 缺點(diǎn):很多情況下都要采用REST等同步通信協(xié)議API,不能替換為異步;


      異步交互方式提交訂單流程圖
  • 復(fù)制數(shù)據(jù)
    • 下圖解:Consumer Service和Restaurant Service在它們的數(shù)據(jù)發(fā)生變化時對外發(fā)布事件;Order Service訂閱這些事件,并據(jù)此更新自己的數(shù)據(jù)副本;
    • 缺點(diǎn):當(dāng)數(shù)據(jù)量巨大時效率低下;
復(fù)制數(shù)據(jù)提交訂單流程圖
  • 先返回響應(yīng),再完成處理
    • 下圖解:Order Service創(chuàng)建一個未檢驗(Pending)狀態(tài)的訂單,然后通過異步交互方式直接跟其他服務(wù)通信來完成驗證;
    • 缺點(diǎn):使客戶端更復(fù)雜。
先返回響應(yīng),再完成處理訂單流程


5. 本章小結(jié)

  • 微服務(wù)架構(gòu)是一種分布式架構(gòu),因此進(jìn)程間通信起著關(guān)鍵作用;
  • 仔細(xì)管理服務(wù)API的演化至關(guān)重要。向后兼容的更改是最容易進(jìn)行的,因為它們不會影響客戶端。如果對服務(wù)的API進(jìn)行重大更改,通常需要同時支持舊版本和新版本,直到客戶端升級為止;
  • 有許多進(jìn)程間通信技術(shù),每種技術(shù)都有不同的利弊。一個關(guān)鍵的設(shè)計決策是選擇同步遠(yuǎn)程過程調(diào)用模式或異步消息模式?;谕竭h(yuǎn)程過程調(diào)用的協(xié)議(如REST)是最容易使用的。但是,理想情況下,服務(wù)應(yīng)使用異步消息進(jìn)行通信,以提高可用性;
  • 為了防止故障通過系統(tǒng)層層蔓延,使用同步協(xié)議服務(wù)的客戶端必須設(shè)計成能夠處理局部故障,這些故障是在被調(diào)用的服務(wù)停機(jī)或表現(xiàn)出高延遲時發(fā)生的。特別是,它必須在發(fā)出請求時使用超時,限制未完成請求的數(shù)量,并使用斷路器模式來避免調(diào)用失敗的服務(wù);
  • 使用同步協(xié)議的架構(gòu)必須包含服務(wù)發(fā)現(xiàn)機(jī)制,以便客戶端確定服務(wù)實例的網(wǎng)絡(luò)位置。最簡單的方法是使用部署平臺實現(xiàn)的服務(wù)發(fā)現(xiàn)機(jī)制:服務(wù)器端發(fā)現(xiàn)和第三方注冊模式。但另一種方法是在應(yīng)用程序級別實現(xiàn)服務(wù)發(fā)現(xiàn):客戶的發(fā)現(xiàn)和自注冊模式。它需要的工作量更大,但它確實可以處理服務(wù)在多個部署平臺上運(yùn)行的場景;
  • 設(shè)計基于消息的架構(gòu)的一種好方法是使用消息和通道模型,它抽象底層消息系統(tǒng)的細(xì)節(jié)。然后,你可以將該設(shè)計映射到特定的消息基礎(chǔ)結(jié)構(gòu),該基礎(chǔ)結(jié)構(gòu)通常基于消息代理;
  • 使用消息機(jī)制的一個關(guān)鍵挑戰(zhàn)是以原子化的方式同時完成數(shù)據(jù)庫更新和發(fā)布消息。一個好的解決方案是使用事務(wù)性發(fā)件箱模式,并首先將消息作為數(shù)據(jù)庫事務(wù)的一部分寫入數(shù)據(jù)庫。然后,一個單獨(dú)的進(jìn)程使用輪詢發(fā)布者模式或事務(wù)日志拖尾模式從數(shù)據(jù)庫中檢索信息,并將其發(fā)布給消息代理。


最后

\color{blue}{\rm\small{新人制作,如有錯誤,歡迎指出,感激不盡!}}

\color{blue}{\rm\small{歡迎關(guān)注我,并與我交流!}}

\color{blue}{\rm\small{如需轉(zhuǎn)載,請標(biāo)注出處!}}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容