微服務(wù)架構(gòu)的通信設(shè)計模式
今天我們來學(xué)習(xí)一下微服務(wù)的通信設(shè)計模式,通信是保證服務(wù)請求核心要素,選擇合適的一個通信協(xié)議對系統(tǒng)來說可以達到事半功倍。
一、RPC調(diào)用模式
目前各種微服務(wù)通信社區(qū)上,很多種支持RPC模式。有同步請求/響應(yīng)通信機制,例如基于 HTTP 的 REST 或 GraphQL,或 gRPC?;蛘呖梢允褂卯惒降?、基于消息的通信機制,例如 AMQP(高級消息隊列協(xié)議)或 STOMP(簡單/流式面向文本的消息傳遞協(xié)議)。此外,還有許多不同的消息格式。這些格式可以是可讀的,例如 JSON 和 XML。他們還可以使用更高效的二進制格式,例如 Avro 或 Protobuf。
1、RPC 選擇因素
在選擇 RPC 機制之前,考慮一下服務(wù)與其客戶端之間的交互方式是很有必要的??蛻舴?wù)交互有兩個維度。
(1)一對一還是一對多
- 一對一:每個客戶端請求都由一個服務(wù)處理。
- 一對多:每個客戶端請求都由多個服務(wù)處理。
(2)同步的還是異步的
- 同步:客戶端在等待服務(wù)響應(yīng)時可能會阻塞。
- 異步:客戶端不會阻塞,并且響應(yīng)(如果有)并不是立即發(fā)送。
2、一對一互動
- 同步請求/響應(yīng):服務(wù)客戶端請求服務(wù)并等待響應(yīng)。服務(wù)的緊密耦合是這種交互方式的結(jié)果。
- 異步請求/響應(yīng):服務(wù)客戶端向服務(wù)發(fā)送請求,服務(wù)異步回復(fù)。
- 單向通知:客戶端向服務(wù)發(fā)送請求,但不期待響應(yīng)。
3、一對多交互
- 異步發(fā)布/訂閱:客戶端發(fā)布通知消息,由一個或多個訂閱服務(wù)使用。
- 異步發(fā)布/異步響應(yīng):在這種情況下,客戶端發(fā)布一條消息,然后等待來自感興趣服務(wù)的響應(yīng)。
4、消息格式
RPC 本質(zhì)上是一種消息交換。其中一個重要的設(shè)計是消息包含數(shù)據(jù)的格式。消息格式的選擇會影響 RPC 的效率、API 的可用性及其可演化性。
消息格式有兩種主要類型:文本和二進制。
(1)基于文本的消息格式
JSON 和 XML 是最流行的基于文本的格式。
基于文本的消息格式的優(yōu)點
- 可讀性高,可自我描述。
基于文本的消息格式的缺點
- 消息很冗長。
- 除了它們的值之外,沒有必要的屬性及其他標簽都會包含其中。
- 解析文本性能開銷很大。
(2)二進制消息格式
Thrift、Protocol Buffers (Protobuf) 和 Avro 是最流行的二進制格式。
二進制消息格式的優(yōu)點
- 元數(shù)據(jù)很少,因此有效負載很小。
- 比基于文本的消息解析要快。
二進制消息格式的缺點
- 可讀性差,不可自我描述
二、遠程過程調(diào)用模式
當客戶端請求服務(wù)時,服務(wù)會處理請求并發(fā)回響應(yīng)。雖然一些客戶端可能會在等待響應(yīng)時阻塞,但其他客戶端可能具有反應(yīng)性、非阻塞架構(gòu)。
代理接口通常封裝底層通信協(xié)議。
有多種通信協(xié)議可供選擇,例如 REST、gRPC 和 GraphQL 等。
三、使用同步模式進行通信
1、REST(代表性狀態(tài)轉(zhuǎn)移)
REST 基于資源的概念,它表示單個業(yè)務(wù)對象。HTTP(超文本傳輸協(xié)議)用于實現(xiàn) REST。REST 使用 HTTP 來操作由 URL 引用的資源。
2、HTTP 調(diào)用方式
- GET: GET 方法向特定的資源發(fā)出請求。GET方法不應(yīng)當被用于產(chǎn)生“副作用”的操作中,例如在Web Application中,其中一個原因是GET可能會被網(wǎng)絡(luò)蜘蛛等隨意訪問
- HEAD: HEAD 方法向服務(wù)器索與GET請求相一致的響應(yīng),只不過響應(yīng)體將不會被返回。這一方法可以在不必傳輸整個響應(yīng)內(nèi)容的情況下,就可以獲取包含在響應(yīng)小消息頭中的元信息。
- POST: POST請求數(shù)據(jù)被包含在請求體中。POST請求可能會導(dǎo)致新的資源的建立和/或已有資源的修改。
- PUT: PUT 方法用請求有效負載替換目標資源的所有當前表示。
- DELETE: DELETE 方法請求服務(wù)器刪除Request-URL所標識的資源
- CONNECT: CONNECT 方法建立由目標資源標識的服務(wù)器的隧道。
- OPTIONS: OPTIONS 方法描述了目標資源的通信選項。
- TRACE: TRACE 方法沿到目標資源的路徑執(zhí)行消息環(huán)回測試。
- PATCH: PATCH 方法將部分修改應(yīng)用于資源。
3、指定 REST API
API 必須使用 IDL(接口定義語言)定義。最流行的 REST IDL 之一是開放 API 規(guī)范,它是從Swagger開源項目演變而來的。
4、挑戰(zhàn)一:在單個請求中獲取多個資源
由于 REST API 通?;跇I(yè)務(wù)對象,因此在一個請求中請求多個相關(guān)對象是設(shè)計 REST API 時的常見難題之一。客戶端必須至少對相關(guān)對象發(fā)出多次請求。
使用查詢參數(shù),API 可以使客戶端在獲取資源時檢索相關(guān)資源。由于這種方法缺乏可擴展性,GraphQL和Netflix Falcor等替代 API 技術(shù)變得越來越受歡迎。
5、挑戰(zhàn)二:映射操作到 HTTP 動詞
另一個常見的 REST API 設(shè)計問題是將要對業(yè)務(wù)對象執(zhí)行的操作映射到 HTTP 請求上。REST API 使用 PUT 來更新,但是有多種方法可以操作訂單,包括取消訂單、修改訂單等。一種解決方案是定義一個子資源,如 /orders/{orderId}/cancel 或 /orders/{orderId}/revise 以更新資源的特定方面或在 URL 查詢參數(shù)中指定動詞。但這些解決方案并不是真正的 RESTful。
由于這個問題,REST 的替代品(例如gRPC)越來越受歡迎。
6、REST 的優(yōu)勢
- 目前很多微服務(wù)框架都支持REST,實現(xiàn)起來相對容易
- Postman 等插件可以輕松地在瀏覽器中測試 HTTP API。
- 它支持直接請求/響應(yīng)通信。
7、REST 的缺點
- 僅支持請求/響應(yīng)通信。
- 由于要求客戶端和服務(wù)器同時在線,可用性降低。
- 客戶端必須使用服務(wù)發(fā)現(xiàn)來發(fā)現(xiàn)服務(wù)實例的 URL。
- 在一個請求中獲取多個資源可能具有挑戰(zhàn)性。
- 將多個更新操作映射到 HTTP 動詞可能具有挑戰(zhàn)性。
四、gRPC
由于 HTTP 僅提供一組有限的請求方式,因此設(shè)計支持多個更新操作的 REST API 可能具有挑戰(zhàn)性。
谷歌推出的跨語言客戶端和服務(wù)器的框架 gRPC 可以解決這個問題。使用基于協(xié)議緩沖區(qū)的 IDL 定義 gRPC API,這是 Google 用于序列化結(jié)構(gòu)化數(shù)據(jù)的語言設(shè)計機制。是一種同步通信機制。使用 HTTP/2,客戶端和服務(wù)器以協(xié)議緩沖區(qū)格式交換二進制消息。
1、gRPC 的優(yōu)勢
- 易于設(shè)計具有豐富更新操作集的 API 。
- 消息格式緊湊且高效。
- 雙向流使 RPC 和消息傳遞成為可能。
- 它支持以多種語言編寫的客戶端和服務(wù)的互操作性。
2、gRPC 的缺點
- JS 客戶端必須做更多的工作來使用基于 gRPC 的 API,而不是基于 REST/JSON 的 API。
五、GraphQL
GraphQL 解決了使用單個請求獲取多個資源的問題。GraphQL 主要用于從客戶端應(yīng)用程序查詢數(shù)據(jù)庫。在后端,GraphQL 向 API 指定如何將數(shù)據(jù)呈現(xiàn)給客戶端。GraphQL 重新定義了開發(fā)人員使用 API 的方式,提供更大的靈活性和更快的上線速度;改進了客戶端-服務(wù)器交互,使前者能夠進行精確的數(shù)據(jù)請求,并只獲得他們需要的數(shù)據(jù)。
GraphQL 服務(wù)器為客戶端提供模式:可以請求的數(shù)據(jù)模型。
1、GraphQL 的優(yōu)勢
- 客戶端可以準確地從服務(wù)器指定他們需要什么,服務(wù)器將以可預(yù)測的方式反饋該數(shù)據(jù)。
- API 使用者確切地知道哪些數(shù)據(jù)可用以及它是什么形式,因為它是強類型的。
2、GraphQL 的缺點
- 無論查詢成功與否,它總是返回一個 HTTP 狀態(tài)碼 200。
- 沒有內(nèi)置緩存支持
- 它比 REST 更復(fù)雜
六、使用異步消息傳遞模式進行通信
使用消息傳遞時,服務(wù)會異步交換消息?;谙⒌膽?yīng)用程序通常使用像 RabbitMQ 這樣的消息代理,充當服務(wù)之間的中介。服務(wù)客戶端通過向服務(wù)發(fā)送消息來向服務(wù)發(fā)出請求。如果期望響應(yīng),服務(wù)實例將向客戶端發(fā)送單獨的消息。由于通信是異步的,客戶端不會等待響應(yīng)。相反,客戶端是假設(shè)不會立即收到響應(yīng)的。
1、單向通知
異步消息傳遞使實現(xiàn)單向通知變得容易。通常,客戶端向服務(wù)擁有的點對點通道發(fā)送消息。服務(wù)訂閱頻道處理消息。沒有響應(yīng)被發(fā)回。
2、發(fā)布/訂閱
發(fā)布/訂閱交互樣式內(nèi)置于消息傳遞中。客戶端將消息發(fā)布到由多個訂閱者讀取的發(fā)布-訂閱通道。
3、發(fā)布/異步響應(yīng)
結(jié)合了發(fā)布/訂閱和請求/響應(yīng)的元素,形成了更高層次的交互風(fēng)格??蛻舳藢⒅付ɑ貜?fù)通道頭的消息發(fā)布到發(fā)布-訂閱通道。消費者將包含相關(guān) id 的回復(fù)消息寫入回復(fù)通道??蛻舳死孟嚓P(guān) id 將回復(fù)消息與收集響應(yīng)的請求進行匹配。