gRPC核心概念

此文翻譯的原文地址:gRPC Concepts

綜述

服務定義

和許多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 RPC:客戶端向服務器端發送請求,並得到響應,類似於方法調用:
rpc SayHello(HelloRequest) returns (HelloResponse);
  • Server streaming RPC:客戶端可以向服務器發送請求,獲取服務端返回的流響應,客戶端可從流中讀取一組消息。客戶端可以持續讀取消息直至消息全部讀取完成。gRPC保證消息順序的正確性:
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
  • Client streaming RPC:客戶端會寫入一組消息,然後基於流的方式發送給服務端。當客戶端寫完全部消息後,就等待服務端進行消息的讀取並等待服務端響應。gRPC保證消息順序的正確性:
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  • Bidirectional streaming RPC:服務端和客戶端都可以使用讀寫流發送一組消息。服務端的流和客戶端的流是相互獨立的,所以服務端和客戶端可以按照自己的方式進行流的寫入和讀取。如:服務端可以決定在全部接收完客戶端發送的消息後再進行響應,或者它可以讀取一條消息,就寫入一條消息,或者其他的一些讀寫組合。同樣的在流中的消息的順序是可以保證的。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

使用API

在我們在一個.proto文件中定義完服務後,gRPC提供protocol buffers編譯器插件來產生客戶端和服務端代碼。gRPC通常是在客戶端進行調用,在服務端實現服務定義的方法:

  • 在服務端,會實現服務中聲明的方法,然後啓動一個gRPC服務器用於響應客戶端的請求。gRPC底層邏輯會正確的把接收到的請求信息轉化爲對應的參數類型、進行方法調用,然後返回響應;
  • 在客戶端,有一個本地對象實現了服務的同樣的方法。客戶端可以直接調用本地對象上的方法,gRPC會自動的發送請求,並正確的得到響應;

同步和異步

同步調用會阻塞客戶端代碼執行,知道從服務端得到響應。這種方式是和RPC想要達到的模擬本地調用的目的最接近的一種方式。但是在另一方面,網絡本質上就是異步的,而且在一些場景下,不阻塞客戶端代碼執行也會非常有用處。
gRPC在大多數的語言中都支持同步和異步的調用。

RPC生命週期

在這一部分我們會詳細看看在一個gRPC客戶端調用服務端方法時發生了哪些事情

Unary RPC

首先讓我們看看最簡單的RPC調用方式 – 客戶端發送一個請求並獲取一個響應。
當客戶端調用本地的樁方法時,服務端會得到一個RPC被調用的通知,通知中包含了關於此次調用的元數據信息:方法名、指定的合適的超時時間。
服務端可以立即返回一些關於它自己的初始化元數據(必須在響應發送前發送),或者等待客戶端的請求信息,當然這兩種方式是和具體的應用相關的。
當服務端接收到客戶端的請求信息後,它會執行具體的邏輯以便產生一個響應。響應會和一個描述狀態的詳細信息(狀態碼和可選的狀態信息)及一個可選的附屬的元數據一起發送給客戶端。
如果響應的狀態是OK,則客戶端就得到了響應,完成了一次RPC的調用。

Server streaming RPC

server-streaming RPC和unary RPC類似,不同點在於服務端不再返回一個簡單的響應,而是返回一個信息流。在信息流發送完成後,服務端的描述狀態的詳細信息(狀態碼和可選的狀態信息)及一個可選的附屬的元數據就會發送給客戶端。這樣就完成了服務端的處理;當客戶端獲取了所有的消息後,就完成此次的調用全過程。

Client streaming RPC

client streaming RPC和unary RPC類似,不同點在於客戶端不是發送一個簡單的請求而是一個消息流。服務端會返回一個響應(包括了處理狀態的詳細信息和一個可選的附屬的元數據),這個響應可在服務端接收完全部消息後進行返回,也可以在接收的過程中就進行返回。

Bidirectional streaming RPC

在bidirectional streaming RPC調用過程中,調用是由客戶端發起的,服務端會得到客戶端的元數據、調用的方法名和超時時間。服務端可以選擇立即向客戶端發送初始化元數據或等待客戶端發送消息流。
客戶端和服務端的流的處理方式都是和應用相關的。因爲客戶端的流和服務端的流是獨立的,所以客戶端和服務端可以以不同的順序進行消息的讀寫。

Deadlines/Timeouts

gRPC允許客戶端指定在RPC通過DEADLINE_EXCEEDED錯誤終止前希望等待的時間。在服務端可以查看一個特定的RPC是否已經超時了,或者在完成一次RPC前還剩下多少時間。
使用deadline還是timeout進行超時指定是由特定的語言自己決定的:一些語言使用timeout(調用可持續的時間段),一些語言使用deadline(固定的時間點),是否有缺省值也是由具體的語言決定的。

RPC termination

gRPC中,客戶端和服務端對於調用是否成功的判定是相互獨立的,而且他們的結論也可能是不同的。這意味着在服務端一個RPC調用已經正常完成了(發送了所有的消息),但是在客戶端卻失敗了(消息是超時後才收到的)。另外在客戶端發送完所有的消息前,服務端就可能正常的結束一個調用。

Cancelling an RPC

服務端和客戶端都可以在一個RPC調用過程中取消調用。取消會立即終止RPC調用,以防止產生無效的其他消耗。但是這種取消,不會回滾所有已經作出的變更。

Metadata

Metadata是以key-value形式描述一次特定的RPC調用(如:認證詳細信息)的信息。 其中key一定是一個字符串,而value通常是字符串,但也可以是二進制數據。Metadata對於gRPC來說比較難理解:它讓客戶端提供關於一次調用的相關信息,反之亦然。
對於Metadata的訪問,是由各個實現語言自己控制的。

Channels

gRPC channel提供了一個特定gRPC服務端的連接。它用於創建客戶端樁代碼。客戶端通過指定channel的參數來改變gRPC的默認行爲,如:是否打開壓縮消息的能力。Channel是有狀態的,如:已經連接或空閒的。
對於如何關閉一個channel,每個語言都有自己不同的方式。有些語言還允許查詢channel的狀態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章