微服務架構的通訊設計模式
昨天我們一起學習的微服務資料模式,今天我們來學習一下微服務的通訊設計模式,通訊是保證服務請求核心要素,選擇合適的一個通訊協議對系統來說可以達到事半功倍。
一、RPC呼叫模式
目前各種微服務通訊社群上,很多種支援RPC模式。有同步請求/響應通訊機制,例如基於 HTTP 的 REST 或 GraphQL,或 gRPC。或者可以使用非同步的、基於訊息的通訊機制,例如 AMQP(高階訊息佇列協議)或 STOMP(簡單/流式面向文字的訊息傳遞協議)。此外,還有許多不同的訊息格式。這些格式可以是可讀的,例如 JSON 和 XML。他們還可以使用更高效的二進位制格式,例如 Avro 或 Protobuf。
1.1 RPC 選擇因素
在選擇 RPC 機制之前,考慮一下服務與其客戶端之間的互動方式是很有必要的。客戶服務互動有兩個維度。
1.1.1 一對一還是一對多
一對一 :每個客戶端請求都由一個服務處理。
一對多 :每個客戶端請求都由多個服務處理。
1.1.2 同步的還是非同步的
同步:客戶端在等待服務響應時可能會阻塞。
非同步 :客戶端不會阻塞,並且響應(如果有)並不是立即傳送。
1.2 一對一互動
同步請求/響應 :服務客戶端請求服務並等待響應。服務的緊密耦合是這種互動方式的結果。
非同步請求/響應 :服務客戶端向服務傳送請求,服務非同步回覆。
單向通知 :客戶端向服務傳送請求,但不期待響應。
1.3 一對多互動
非同步釋出/訂閱 :客戶端釋出通知訊息,由一個或多個訂閱服務使用。
非同步釋出/非同步響應 :在這種情況下,客戶端釋出一條訊息,然後等待來自感興趣服務的響應。
1.4 訊息格式
RPC 本質上是一種訊息交換。其中一個重要的設計是訊息包含資料的格式。訊息格式的選擇會影響 RPC 的效率、API 的可用性及其可演化性。
訊息格式有兩種主要型別:文字和二進位制。
1.4.1 基於文字的訊息格式
JSON 和 XML 是最流行的基於文字的格式。
基於文字的訊息格式的優點
可讀性高,可自我描述。
基於文字的訊息格式的缺點
訊息很冗長。
除了它們的值之外,沒有必要的屬性及其他標籤都會包含其中。
解析文字效能開銷很大。
1.4.2 二進位制訊息格式
Thrift、Protocol Buffers (Protobuf) 和 Avro 是最流行的二進位制格式。
二進位制訊息格式的優點
元資料很少,因此有效負載很小。
比基於文字的訊息解析要快。
二進位制訊息格式的缺點
可讀性差,不可自我描述
二、遠端過程呼叫模式
當客戶端請求服務時,服務會處理請求併發迴響應。雖然一些客戶端可能會在等待響應時阻塞,但其他客戶端可能具有反應性、非阻塞架構。
代理介面通常封裝底層通訊協議。
有多種通訊協議可供選擇,例如 REST、gRPC 和 GraphQL 等。
三、使用同步模式進行通訊
3.1 REST(代表性狀態轉移)
REST 基於資源的概念,它表示單個業務物件。HTTP(超文字傳輸協議)用於實現 REST。REST 使用 HTTP 來操作由 URL 引用的資源。
3.2 HTTP 呼叫方式
GET: GET 方法向特定的資源發出請求。GET方法不應當被用於產生“副作用”的操作中,例如在Web Application中,其中一個原因是GET可能會被網路蜘蛛等隨意訪問
HEAD: HEAD 方法向伺服器索與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應小訊息頭中的元資訊。
POST: POST請求資料被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
PUT: PUT 方法用請求有效負載替換目標資源的所有當前表示。
DELETE: DELETE 方法請求伺服器刪除Request-URL所標識的資源
CONNECT: CONNECT 方法建立由目標資源標識的伺服器的隧道。
OPTIONS: OPTIONS 方法描述了目標資源的通訊選項。
TRACE: TRACE 方法沿到目標資源的路徑執行訊息環回測試。
PATCH: PATCH 方法將部分修改應用於資源。
3.3 指定 REST API
API 必須使用 IDL(介面定義語言)定義。最流行的 REST IDL 之一是開放 API 規範,它是從Swagger開源專案演變而來的。
3.4 挑戰一:在單個請求中獲取多個資源
由於 REST API 通常基於業務物件,因此在一個請求中請求多個相關物件是設計 REST API 時的常見難題之一。客戶端必須至少對相關物件發出多次請求。
使用查詢引數,API 可以使客戶端在獲取資源時檢索相關資源。由於這種方法缺乏可擴充套件性,GraphQL和Netflix Falcor等替代 API 技術變得越來越受歡迎。
3.5 挑戰二:對映操作到 HTTP 動詞
另一個常見的 REST API 設計問題是將要對業務物件執行的操作對映到 HTTP 請求上。REST API 使用 PUT 來更新,但是有多種方法可以操作訂單,包括取消訂單、修改訂單等。一種解決方案是定義一個子資源,如 /orders/{orderId}/cancel 或 /orders/{orderId}/revise 以更新資源的特定方面或在 URL 查詢引數中指定動詞。但這些解決方案並不是真正的 RESTful。
由於這個問題,REST 的替代品(例如gRPC)越來越受歡迎。
3.5 REST 的優勢
目前很多微服務框架都支援REST,實現起來相對容易
Postman 等外掛可以輕鬆地在瀏覽器中測試 HTTP API。
它支援直接請求/響應通訊。
3.6 REST 的缺點
僅支援請求/響應通訊。
由於要求客戶端和伺服器同時線上,可用性降低。
客戶端必須使用服務發現來發現服務例項的 URL。
在一個請求中獲取多個資源可能具有挑戰性。
將多個更新操作對映到 HTTP 動詞可能具有挑戰性。
四、gRPC
由於 HTTP 僅提供一組有限的請求方式,因此設計支援多個更新操作的 REST API 可能具有挑戰性。
谷歌推出的跨語言客戶端和伺服器的框架 gRPC 可以解決這個問題。使用基於協議緩衝區的 IDL 定義 gRPC API,這是 Google 用於序列化結構化資料的語言設計機制。是一種同步通訊機制。使用 HTTP/2,客戶端和伺服器以協議緩衝區格式交換二進位制訊息。
4.1 gRPC 的優勢
易於設計具有豐富更新操作集的 API 。
訊息格式緊湊且高效。
雙向流使 RPC 和訊息傳遞成為可能。
它支援以多種語言編寫的客戶端和服務的互操作性。
4.2 gRPC 的缺點
JS 客戶端必須做更多的工作來使用基於 gRPC 的 API,而不是基於 REST/JSON 的 API。
五、GraphQL
GraphQL 解決了使用單個請求獲取多個資源的問題。GraphQL 主要用於從客戶端應用程式查詢資料庫。在後端,GraphQL 向 API 指定如何將資料呈現給客戶端。GraphQL 重新定義了開發人員使用 API 的方式,提供更大的靈活性和更快的上線速度;改進了客戶端-伺服器互動,使前者能夠進行精確的資料請求,並只獲得他們需要的資料。
GraphQL 伺服器為客戶端提供模式:可以請求的資料模型。
5.1 GraphQL 的優勢
客戶端可以準確地從伺服器指定他們需要什麼,伺服器將以可預測的方式反饋該資料。
API 使用者確切地知道哪些資料可用以及它是什麼形式,因為它是強型別的。
5.2 GraphQL 的缺點
無論查詢成功與否,它總是返回一個 HTTP 狀態碼 200。
沒有內建快取支援
它比 REST 更復雜
六、使用非同步訊息傳遞模式進行通訊
使用訊息傳遞時,服務會非同步交換訊息。基於訊息的應用程式通常使用像 RabbitMQ 這樣的訊息代理,充當服務之間的中介。服務客戶端通過向服務傳送訊息來向服務發出請求。如果期望響應,服務例項將向客戶端傳送單獨的訊息。由於通訊是非同步的,客戶端不會等待響應。相反,客戶端是假設不會立即收到響應的。
6.1 單向通知
非同步訊息傳遞使實現單向通知變得容易。通常,客戶端向服務擁有的點對點通道傳送訊息。服務訂閱頻道處理訊息。沒有響應被髮回。
6.2 釋出/訂閱
釋出/訂閱互動樣式內置於訊息傳遞中。客戶端將訊息釋出到由多個訂閱者讀取的釋出-訂閱通道。
6.3 釋出/非同步響應
結合了釋出/訂閱和請求/響應的元素,形成了更高層次的互動風格。客戶端將指定回覆通道頭的訊息釋出到釋出-訂閱通道。消費者將包含相關 id 的回覆訊息寫入回覆通道。客戶端利用相關 id 將回復訊息與收集響應的請求進行匹配。
- 天翼雲全場景業務無縫替換至國產原生作業系統CTyunOS!
- 以羊了個羊為例,淺談小程式抓包與響應報文修改
- 這幾種常見的 JVM 調優場景,你知道嗎?
- 如此狂妄,自稱高效能佇列的Disruptor有啥來頭?
- 為什麼要學習GoF設計模式?
- 827. 最大人工島 : 簡單「並查集 列舉」運用題
- 手把手教你如何使用 Timestream 實現物聯網時序資料儲存和分析
- 850. 矩形面積 II : 掃描線模板題
- Java 併發程式設計解析 | 基於JDK原始碼解析Java領域中的併發鎖,我們可以從中學習到什麼內容?
- 【手把手】光說不練假把式,這篇全鏈路壓測實踐探索
- 大廠鍾愛的全鏈路壓測有什麼意義?四種壓測方案詳細對比分析
- 寫個續集,填坑來了!關於“Thread.sleep(0)這一行‘看似無用’的程式碼”裡面留下的坑。
- 857. 僱傭 K 名工人的最低成本 : 列舉 優先佇列(堆)運用題
- Vue3 實現一個自定義toast(小彈窗)
- 669. 修剪二叉搜尋樹 : 常規樹的遍歷與二叉樹性質
- 讀完 RocketMQ 原始碼,我學會了如何優雅的建立執行緒
- 效能調優——小小的log大大的坑
- 1582. 二進位制矩陣中的特殊位置 : 簡單模擬題
- elementui原始碼學習之仿寫一個el-switch
- 646. 最長數對鏈 : 常規貪心 DP 運用題