一起玩轉微服務(6)——通訊協議如何統一

skyme發表於2020-06-20

一、介面呼叫

介面呼叫如果是遠端呼叫,那麼就構成了簡單的分散式。最簡單的遠端介面實現方式是web service或rest。當然一個合理的分散式應用不僅僅是遠端介面呼叫這麼簡單。還需要有負載均衡、快取等功能。最簡單實現分散式的技術是Rest介面,因為Rest介面可以使用現存的各種伺服器,比如負載均衡伺服器和快取伺服器來實現負載均衡和快取功能。

二、統一通訊協議

關於通訊協議,不同的公司有不同的選擇,但是建議同一公司內部使用統一的通訊協議,比較典型的有grpc和brpc。

1. gRPC簡介

gRPC是Google釋出的基於HTTP 2.0傳輸層協議承載的高效能開源軟體框架,提供了支援多種程式語言的、對網路裝置進行配置和納管的方法。由於是開源框架,通訊的雙方可以進行二次開發,所以客戶端和伺服器端之間的通訊會更加專注於業務層面的內容,減少了對由gRPC框架實現的底層通訊的關注。如下圖,DATA部分即業務層面內容,下面所有的資訊都由gRPC進行封裝。

 

 

grpc是一個高效能、開源和通用的 RPC 框架,面向移動和 HTTP/2 設計。目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go. 其中 C 版本支援 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支援.
grpc基於 HTTP/2 標準設計,帶來諸如雙向流、流控、頭部壓縮、單 TCP 連線上的多複用請求等特。這些特性使得其在移動裝置上表現更好,更省電和節省空間佔用。
關於具體gRPC報文的結構,可以參考下圖:

 

 

下面展示一下gRPC的互動過程

 

 

  1. 交換機在開啟gRPC功能後充當gRPC客戶端的角色,採集伺服器充當gRPC伺服器角色;
  2. 交換機會根據訂閱的事件構建對應資料的格式(GPB/JSON),通過Protocol Buffers進行編寫proto檔案,交換機與伺服器建立gRPC通道,通過gRPC協議向伺服器傳送請求訊息;
  3. 伺服器收到請求訊息後,伺服器會通過Protocol Buffers解譯proto檔案,還原出最先定義好格式的資料結構,進行業務處理;
  4. 資料梳理完後,伺服器需要使用Protocol Buffers重編譯應答資料,通過gRPC協議向交換機傳送應答訊息;
  5. 交換機收到應答訊息後,結束本次的gRPC互動。

上圖展示的是gRPC互動過程的具體流程,這也是Telemetry觸發方式其中之一,稱為Dial-out模式。簡單地說,gRPC就是在客戶端和伺服器端開啟gRPC功能後建立連線,將裝置上配置的訂閱資料推送給伺服器端。

2. brpc

與grpc類似,brpc源自百度,目前支撐百度內部大約 75 萬個同時線上的例項。
其實基於以上的幾種選擇都能夠完成高效的開發,團隊內部使用統一的標準,這樣更有利於模組化和統一標準。
服務間的通訊是通過輕量級的web服務,使用同步的REST API進行通訊。在實際的專案應用中,一般推薦在查詢的時候使用同步機制,在增刪改使用非同步的方式,結合訊息佇列來實現資料的操作,以保證最終的資料一致性。
具體可以使用BRPC做如下

  1. 搭建能在一個埠支援多協議的服務, 或訪問各種服務
  2. Server能同步或非同步處理請求
  3. Client支援同步、非同步、半同步,或使用組合channels簡化複雜的分庫或併發訪問
  4. 通過http介面除錯服務, 使用cpu, heap, contention profilers
  5. 獲得更好的延時和吞吐
  6. 把你組織中使用的協議快速地加入brpc,或定製各類元件, 包括命名服務 (dns, zk, etcd), 負載均衡 (rr, random, consistent hashing)

三、rest API

 

 

REST API 應為建立、檢索、更新和刪除操作使用標準 HTTP 動詞,而且應特別注意操作是否冪等。
POST 操作可用於建立資源。POST 操作的明顯特徵是它不是冪等的。舉例而言,如果使用 POST 請求建立資源,而且啟動該請求多次,那麼每次呼叫後都會建立一個新的唯一資源。
GET 操作必須是冪等的且不會產生意外結果。具體來講,帶有查詢引數的 GET 請求不應用於更改或更新資訊(而應使用 POST、PUT 或 PATCH)。
PUT 操作可用於更新資源。PUT 操作通常包含要更新的資源的完整副本,使該操作具有冪等性。
PATCH 操作允許對資源執行部分更新。它們不一定是冪等的,具體取決於如何指定增量並應用到資源上。例如,如果一個 PATCH 操作表明一個值應從 A 改為 B,那麼它就是冪等的。如果它已啟動多次而且值已是 B,則沒有任何效果。對 PATCH 操作的支援仍不一致。例如,Java EE7 中的 JAX-RS 中沒有 @PATCH 註釋。
DELETE 操作用於刪除資源。刪除操作是冪等的,因為資源只能刪除一次。但是,返回程式碼不同,因為第一次操作將成功 (200),而後續呼叫不會找到資源 (204)。

 

四、你們怎麼解決

不同專案組之間使用的語言有可能不同,框架有可能不同,同樣的,通訊協議有可能不同,你們怎麼解決的呢?

相關文章