gRPC系列 :RPC 框架原理是?gRPC 是什麼?gRPC設計原則

1. RPC 入門

1.1 RPC 框架原理

RPC 框架的目標就是讓遠程服務調用更加簡單、透明,RPC 框架負責屏蔽底層的傳輸方式(TCP 或者 UDP)、序列化方式(XML/Json/ 二進制)和通信細節服務調用者可以像調用本地接口一樣調用遠程的服務提供者,而不需要關心底層通信細節和調用過程。

RPC 框架的調用原理圖如下所示:

 整理成序列圖後的效果是:

RPC 框架--時序圖​​

1.2 業界主流的 RPC 框架

業界主流的 RPC 框架整體上分爲三類:

  • 支持多語言的 RPC 框架,比較成熟的有 Google 的 gRPC、Apache(Facebook)的 Thrift;
  • 只支持特定語言的 RPC 框架,例如新浪微博的 Motan;
  • 支持服務治理等服務化特性的分佈式服務框架,其底層內核仍然是 RPC 框架, 例如阿里的 Dubbo。

隨着微服務的發展,基於語言中立性原則構建微服務,逐漸成爲一種主流模式,例如對於後端併發處理要求高的微服務,比較適合採用 Go 語言構建,而對於前端的 Web 界面,則更適合 Java 和 JavaScript。
因此,基於多語言的 RPC 框架來構建微服務,是一種比較好的技術選擇。例如 Netflix,API 服務編排層和後端的微服務之間就採用 gRPC 進行通信。

2. gRPC

gRPC是一個高性能、開源和通用的 RPC 框架,支持多語言。

gRPC 基於 HTTP/2 標準設計,帶來諸如雙向流、流控、頭部壓縮、單 TCP 連接上的多複用請求等特性。這些特性使得其在移動設備上表現更好,更省電和節省空間佔用。

gRPC 調用模型

1、客戶端(gRPC Stub)調用 A 方法,發起 RPC 調用。

2、對請求信息使用 Protobuf 進行對象序列化壓縮(IDL)

3、服務端(gRPC Server)接收到請求後,解碼請求體,進行業務邏輯處理並返回。

4、對響應結果使用 Protobuf 進行對象序列化壓縮(IDL)

5、客戶端接受到服務端響應,解碼請求體。回調被調用的 A 方法,喚醒正在等待響應(阻塞)的客戶端調用並返回響應結果

  • 一個RPC框架大致需要動態代理、序列化、網絡請求、網絡請求接受(netty實現)、動態加載、反射這些知識點。現在開源及各公司自己造的RPC框架層出不窮,唯有掌握原理是一勞永逸的。

gRPC 是什麼?

在 gRPC 裏客戶端應用可以像調用本地對象一樣直接調用另一臺不同的機器上服務端應用的方法,使得您能夠更容易地創建分佈式應用和服務。與許多 RPC 系統類似,gRPC 也是基於以下理念:定義一個服務,指定其能夠被遠程調用的方法(包含參數和返回類型)。在服務端實現這個接口,並運行一個 gRPC 服務器來處理客戶端調用。在客戶端擁有一個存根能夠像服務端一樣的方法

gRPC 特點

  • 語言中立,支持多種語言;
  • 基於 IDL ( 接口定義語言(Interface Define Language))文件定義服務,通過 proto3 工具生成指定語言的數據結構、服務端接口以及客戶端 Stub;
  • 通信協議基於標準的 HTTP/2 設計,支持·雙向流、消息頭壓縮、單 TCP 的多路複用、服務端推送等特性,這些特性使得 gRPC 在移動端設備上更加省電和節省網絡流量;
  • 序列化支持 PB(Protocol Buffer)和 JSON,PB 是一種語言無關的高性能序列化框架,基於 HTTP/2 + PB, 保障了 RPC 調用的高性能。

gRPC原則和訴求

服務而非對象、消息而非引用 —— 促進微服務的系統間粗粒度消息交互設計理念,同時避免分佈式對象的陷阱和分佈式計算的謬誤。

普遍並且簡單 —— 該基礎框架應該在任何流行的開發平臺上適用,並且易於被個人在自己的平臺上構建。它在CPU和內存有限的設備上也應該切實可行。

免費並且開源 —— 所有人可免費使用基本特性。以友好的許可協議開源方式發佈所有交付件。

互通性 —— 該數據傳輸協議(Wire Protocol)必須遵循普通互聯網基礎框架。

通用並且高性能 —— 該框架應該適用於絕大多數用例場景,相比針對特定用例的框架,該框架只會犧牲一點性能。

分層的 —— 該框架的關鍵是必須能夠獨立演進。對數據傳輸格式(Wire Format)的修改不應該影響應用層。

負載無關的 —— 不同的服務需要使用不同的消息類型和編碼,例如protocol buffers、JSON、XML和Thrift,協議上和實現上必須滿足這樣的訴求。類似地,對負載壓縮的訴求也因應用場景和負載類型不同而不同,協議上應該支持可插拔的壓縮機制。

—— 存儲系統依賴於流和流控來傳遞大數據集。像語音轉文本或股票代碼等其它服務,依靠流表達時間相關的消息序列。

阻塞式和非阻塞式 —— 支持異步和同步處理在客戶端和服務端間交互的消息序列。這是在某些平臺上縮放和處理流的關鍵。

取消和超時 —— 有的操作可能會用時很長,客戶端運行正常時,可以通過取消操作讓服務端回收資源。當任務因果鏈被追蹤時,取消可以級聯。客戶端可能會被告知調用超時,此時服務就可以根據客戶端的需求來調整自己的行爲。

Lameducking —— 服務端必須支持優雅關閉,優雅關閉時拒絕新請求,但繼續處理正在運行中的請求。

流控 —— 在客戶端和服務端之間,計算能力和網絡容量往往是不平衡的。流控可以更好的緩衝管理,以及保護系統免受來自異常活躍對端的拒絕服務(DOS)攻擊。

可插拔的 —— 數據傳輸協議(Wire Protocol)只是功能完備API基礎框架的一部分。大型分佈式系統需要安全、健康檢查、負載均衡和故障恢復、監控、跟蹤、日誌等。實現上應該提供擴展點,以允許插入這些特性和默認實現。

API擴展 ——可能的話,在服務間協作的擴展應該最好使用接口擴展,而不是協議擴展。這種類型的擴展可以包括健康檢查、服務內省、負載監測和負載均衡分配。

元數據交換 —— 常見的橫切關注點,如認證或跟蹤,依賴數據交換,但這不是服務公共接口中的一部分。部署依賴於他們將這些特性以不同速度演進到服務暴露的個別API的能力。

標準化狀態碼 —— 客戶端通常以有限的方式響應API調用返回的錯誤。應該限制狀態代碼名字空間,使得這些錯誤處理決定更清晰。如果需要更豐富的特定域的狀態,可以使用元數據交換機制來提供。



 

發佈了410 篇原創文章 · 獲贊 1345 · 訪問量 208萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章