gRPC理念

本文通過gRPC的結構概述和生命周期介紹一些gRPC理念的關鍵點。

概述

服務定義

就像很多RPC系統一樣,gRPC也是基于定義一個服務的想法,指定可以被遠程調用的方法。默認地,gRPC使用protocol buffers作為接口定義語言 (IDL)來描述服務接口和預加載信息的結構。也可能使用其他替代。

service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

gRPC可以定義四種服務方法:

  • Unary RPCs。比如客戶端向服務端發送一個請求,然后得到一個返回,就像普通的方法調用:
rpc SayHello(HelloRequest) returns (HelloResponse){
}
  • Server streaming RPCs,比如客戶端發送請求到服務端,然后得到一個stream讀取按序返回的messages??蛻舳藦姆祷氐膕tream里讀取直到沒有消息。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
}
  • Client streaming RPCs,比如客戶端寫入一個序列的消息,然后發送到服務端,然后繼續使用提供的stream。當客戶端結束寫入消息后,就會等待服務端讀取后返回數據。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
}
  • 雙向streaming RPCs,客戶端和服務端都發送信息并且讀-寫流。兩個streams獨立操作,所以客戶端和服務端可以按照他們想要的讀取和寫入:比如,服務端可以接收所有的客戶端消息再返回數據或者可以先讀取然后寫數據,或者其他的讀寫組合方式,每個stream的消息順序都已經保存了。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
}

我們在接下來的章節里查看這些不同類型的RPC的詳情。

使用API層

從定義服務的.proto文件開始,gRPC提供protocol buffer編譯插件生成客戶端和服務端的代碼。gRPC用戶在客戶端調用這些APIs,在服務端實現相應的API。

  • 在服務端,服務器實現通過service定義的方法,并且運行一個gRPC服務來處理客戶端調用。gRPC設施解碼請求,執行service方法,然后encode service response.
  • 在客戶端,客戶端有一個已知的本地對象存根(stub)(對于一些語言,首選項是客戶端)實現和服務端相同的方法??蛻舳司涂梢栽诒镜貙ο笊险{用這些方法,為調用在合適的protocol buffer message類型包裝參數 - gRPC隨后發送請求到服務端然后返回服務端的protocol buffer response(s)。
異步 vs. 同步

同步RPC調用會阻塞,直到服務端有返回是最接近RPC的請求過程的抽象。另一方面,網絡本質上是異步的,并且在很多場景,它對在當前線程啟動無阻塞的RPCs很有用。

gRPC編程在大多數語言里都有同步和異步??梢栽诿總€語言里的指南里和相關文檔查看更多。

RPC生命周期

現在我們來看看當gRPC客戶端調用gRPC服務單方法是發生了什么。我們不會看實現細節,你可以在特定語言頁里查看更多。

Unary RPC

首先我們來看最簡單的RPC類型,客戶端發送一個請求并得到一個回復。

  • 一旦客戶端調用方法在stub/client對象上,服務端會被通知到RPC被調用帶著客戶端的metadata, 方法名稱,特定的deadline如果匹配.
  • 服務端然后可以直接返回它的最初的metadata(必須在返回前發送),或者等待客戶端的請求信息 - 一個首先發生的application-specific。
  • 一旦服務端有客戶端的請求信息,創建和填充它的response是必須的。response然后被返回(如果成功)到客戶端帶著狀態詳情(狀態碼和可選的狀態信息)和可選的trailing metadata.
  • 如果狀態是OK的,客戶端會得到響應,客戶端的請求就完成了。
Server streaming RPC

server-streaming RPC和我們簡單的例子相似,除了服務端發送返回一連串的響應在得到客戶端的請求信息后。在發送返回了所有的響應后,服務端的狀態詳情(狀態碼和可選的狀態信息)和可選的trailing metadata會被發送回完成在客戶端。客戶端在得到所有客戶端的相應后完成。

Client streaming RPC

client-streaming RPC也和簡單的例子相同,除了客戶端發送了一系列的請求到客戶端而不是單個請求。服務端返回單個對象,通常但不一定收到了所有客戶的請求后,連同其狀態的細節和可選的元數據。

Bidirectional streaming RPC

在雙向流的RPC里,還是客戶端調用方法然后服務端接收客戶端metaata,方法名稱和deadline。然后服務端可以選擇返回最初的metadata或者等待客戶端開始發送請求。

接下來的情況就取決于應用了,客戶端和服務端都能在任何順序里讀和寫。流操作完全是獨立的。所以,比如,服務端在寫回響應時可以等待直到獲取到所有客戶端的信息,或者服務端和客戶端可以像“乒乓”一樣:服務端獲取請求,然后返回響應,然后客戶端基于返回發送另一個請求,等等。

Deadlines/Timeouts

gRPC允許客戶端為一個RPC完成指定超時時間,不然RPC會被終止,拋出DEADLINE_EXCEEDED錯誤。在服務端,可以查看特定的RPC是否超時,或者還剩下多少時間完成RPC。

如何設置deadline或者timeout取決與不同的語言,比如,不是所有的語言有默認的deadline,有些語言APIs依據deadline(距離上次時間的點),一些依據timeout(間隔)。

RPC termination

在gRPC里,客戶端和服務端是獨立的,并且本地決定請求的成功,但是結論可能不匹配。這意味,比如,你可能有一個RPC在服務端成功的完成了("我已經發送了所有的響應")但是客戶端失敗了(“返回在我的deadline之后”)。當然服務端也可能在客戶端發送所有請求前完成。

Cancelling RPCs

不管是客戶端還是服務端都可以隨時取消RPC。取消會立即終止RPC,首頁不會再工作。這不是“撤銷”: 在取消前已經發生的改變不會被回滾。

Metadata

Metadata是特定RPC請求的信息(比如authentication details)以列表信息的鍵值對,鍵是strings,values通常也是strings(但也可以是binary data)。Metadata對于gRPC是透明的 - 它可以讓客戶端提供調用信息到服務器,或者相反。訪問metadata取決于語言。

Channels

gRPC channels在指定的host和port提供連接到gRPC,在創建客戶端存根的時候使用??蛻舳丝梢灾付ㄌ囟ǖ腸hannel參數修改gRPC的默認行為,比如切換開和關消息壓縮。channel有狀態,包含connectedidle。

gRPC如何處理關閉channel看編程語言。一些語言也允許查詢channel狀態。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容