Service definition
與許多RPC系統(tǒng)一樣,gRPC基于定義服務(wù)的思想淆游,指定可以被遠(yuǎn)程調(diào)用的方法傍睹、參數(shù)隔盛、返回類型。默認(rèn)情況下拾稳,gRPC使用 protocol buffer 作為接口定義語言(IDL)來描述服務(wù)接口和有效負(fù)載消息的結(jié)構(gòu)吮炕。如果需要,可以使用其它替代(如JSON)访得。
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
gRPC 允許你定義四種服務(wù)方法:
-
單向RPC龙亲,客戶端向服務(wù)器發(fā)送一個請求,然后返回一個響應(yīng)悍抑,就像普通的函數(shù)調(diào)用一樣鳄炉。
rpc SayHello(HelloRequest) returns (HelloResponse);
-
服務(wù)器流式RPC,其中客戶端向服務(wù)器發(fā)送一個請求传趾,并獲取一個流以讀回一系列消息迎膜。客戶端從返回的流中讀取消息浆兰,直到不再有消息為止。gRPC保證單個RPC調(diào)用中的消息順序珊豹。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
-
客戶端流式RPC簸呈,其中客戶端寫入一系列消息,并再次使用提供的流將它們發(fā)送到服務(wù)器店茶。一旦客戶機完成了消息的編寫蜕便,它就會等待服務(wù)器讀取消息并返回響應(yīng)。同樣贩幻,gRPC保證了單個RPC調(diào)用中的消息順序轿腺。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
-
雙向流式RPC,其中雙方使用讀寫流發(fā)送一系列消息丛楚。這兩個流是獨立運行的族壳,因此客戶機和服務(wù)器可以按照自己喜歡的順序進(jìn)行讀寫操作:例如,服務(wù)器可以在寫入響應(yīng)之前等待接收所有客戶機消息趣些,或者它可以交替地讀一條消息仿荆,然后再寫一條消息,或者其他一些讀寫組合坏平。每個流中消息的順序都被保留拢操。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
Using the API
從 .proto文件 中的服務(wù)定義開始,gRPC 提供 protocol buffer 編譯器插件舶替,用于生成客戶端和服務(wù)器端代碼令境。gRPC用戶通常在 客戶端調(diào)用這些API,并在 服務(wù)器端實現(xiàn)相應(yīng)的API顾瞪。
在服務(wù)端舔庶,服務(wù)器實現(xiàn)服務(wù)中聲明的方法返劲,運行一個 gRPC 服務(wù)器去處理客戶端請求。gRPC 的基礎(chǔ)設(shè)施對到來的請求解碼栖茉,執(zhí)行服務(wù)方法篮绿,對響應(yīng)進(jìn)行編碼。
在客戶端吕漂,客戶端有一個稱為 stub 的本地對象亲配,它實現(xiàn)與服務(wù)相同的方法。然后惶凝,客戶機就可以在本地對象上調(diào)用這些方法吼虎,將調(diào)用的參數(shù)包裝在適當(dāng)?shù)?protocol buffer 消息類型中—gRPC將請求發(fā)送到服務(wù)器并返回服務(wù)器的protocol buffer 響應(yīng)后進(jìn)行處理。
Synchronous vs. asynchronous
同步RPC調(diào)用苍鲜,在收到服務(wù)器響應(yīng)之前一直阻塞思灰,這與RPC所期望的過程調(diào)用的抽象最接近。另一方面混滔,網(wǎng)絡(luò)本身是異步的洒疚,在許多情況下,能夠在不阻塞當(dāng)前線程的情況下啟動rpc是很有用的坯屿。
大多數(shù)語言中的 gRPC編程API 都有 同步 和 異步 兩種風(fēng)格油湖。您可以在每種語言的教程和參考文檔中找到更多信息。
RPC life cycle
在本節(jié)中领跛,您將更詳細(xì)地了解當(dāng) gRPC客戶機調(diào)用 gRPC服務(wù)器方法時會發(fā)生什么乏德。有關(guān)完整的實現(xiàn)詳細(xì)信息,請參閱特定于語言的文檔吠昭。
Unary PRC
首先考慮最簡單的RPC類型喊括,其中客戶端發(fā)送單個請求并返回單個響應(yīng)。
一旦客戶機調(diào)用一個存根方法矢棚,就會通知服務(wù)器已經(jīng)用客戶機的元數(shù)據(jù)郑什、方法名稱和指定的截止日期(如果適用)調(diào)用了RPC。
然后幻妓,服務(wù)器可以直接發(fā)回自己的初始元數(shù)據(jù)(必須在任何響應(yīng)之前發(fā)送)蹦误,或者等待客戶機的請求消息。首先發(fā)生的是特定于應(yīng)用程序的肉津。
一旦服務(wù)器收到客戶機的請求消息强胰,它就會執(zhí)行創(chuàng)建和填充響應(yīng)所需的任何工作。然后將響應(yīng)(如果成功)連同狀態(tài)詳細(xì)信息(狀態(tài)代碼和可選狀態(tài)消息)和可選的尾部元數(shù)據(jù)一起返回給客戶機妹沙。
如果響應(yīng)狀態(tài)為OK偶洋,那么客戶端將獲得響應(yīng),從而完成客戶端的調(diào)用距糖。
Server streaming RPC
服務(wù)器流RPC類似于一元RPC玄窝,只是服務(wù)器響應(yīng)客戶機的請求返回消息流牵寺。發(fā)送所有消息后,服務(wù)器的狀態(tài)詳細(xì)信息(狀態(tài)代碼和可選的狀態(tài)消息)和可選的尾部元數(shù)據(jù)將發(fā)送到客戶端恩脂。這就完成了服務(wù)器端的處理帽氓。一旦客戶端擁有了服務(wù)器的所有消息,它就完成了俩块。
Client streaming RPC
客戶端流式RPC與一元RPC類似黎休,只是客戶端向服務(wù)器發(fā)送消息流而不是單個消息。服務(wù)器通常(但不一定)在接收到客戶機的所有消息之后玉凯,會用一條消息(連同其狀態(tài)詳細(xì)信息和可選的尾隨元數(shù)據(jù))進(jìn)行響應(yīng)势腮。
Bidirectional streaming RPC
在雙向流RPC中,調(diào)用由調(diào)用方法的客戶端發(fā)起漫仆,服務(wù)端接收客戶端元數(shù)據(jù)捎拯、方法名稱和截止日期。服務(wù)器可以選擇發(fā)回其初始元數(shù)據(jù)或等待客戶端開始流式傳輸消息盲厌。
客戶端和服務(wù)器端流處理是特定于應(yīng)用程序的署照。由于這兩個流是獨立的,客戶機和服務(wù)器可以按任何順序讀寫消息狸眼。例如藤树,服務(wù)器可以等到收到客戶機的所有消息后再寫入其消息,或者 服務(wù)器收到一個請求拓萌,然后發(fā)回一個響應(yīng),然后客戶機根據(jù)響應(yīng)發(fā)送另一個請求升略,依此類推微王。
Deadlines/Timeouts
gRPC允許客戶端指定 在RPC因 DEADLINE_EXCEEDED 錯誤而終止之前曾雕,他們愿意等待RPC完成的時間猾蒂。在服務(wù)器端,服務(wù)器可以查詢特定的RPC是否超時瘤运,或者還剩余多少時間用于完成RPC翰撑。
指定 deadline 或 timeout 是特定于語言的:一些語言 APIs 根據(jù) timeouts(durations of time)工作罩旋,而一些語言 APIs 根據(jù) deadline(a fixed point in time)工作,可能有也可能沒有默認(rèn)的截止時間眶诈。
RPC termination
在gRPC中涨醋,客戶端和服務(wù)器都各自對調(diào)用成功進(jìn)行確定,其結(jié)論可能不匹配逝撬。這意味著浴骂,例如,您可能擁有一個在服務(wù)器端成功完成的RPC(“我已發(fā)送所有響應(yīng)宪潮!”)溯警,而在客戶端卻失敗了(“響應(yīng)在我的截止日期之后到達(dá)趣苏!”)。服務(wù)器還可以在客戶端發(fā)送所有請求之前決定完成梯轻。
Cancelling an RPC
客戶機或服務(wù)器可以隨時取消RPC食磕。取消操作會立即終止RPC,以便不再進(jìn)行進(jìn)一步的工作喳挑。
注意:取消前所做的更改不會回滾彬伦。
Metadata
Metadata 是以 鍵值對列表 的形式表示的關(guān)于特定RPC調(diào)用的信息(例如身份驗證詳細(xì)信息),其中鍵是字符串蟀悦,值通常是字符串媚朦,但可以是二進(jìn)制數(shù)據(jù)。元數(shù)據(jù)對gRPC本身是不透明的-它允許客戶端 向 服務(wù)器提供與調(diào)用相關(guān)的信息日戈,反之亦然询张。
對 Metadata的訪問依賴于 語言。
Channels
gRPC通道 提供到 指定主機和端口上的gRPC服務(wù)器的連接浙炼。它用于創(chuàng)建客戶端存根份氧。客戶機可以指定通道參數(shù)來修改gRPC的默認(rèn)行為弯屈,例如打開或關(guān)閉消息壓縮蜗帜。通道具有狀態(tài),包括已連接( connected )和 空閑( idle )资厉。
gRPC如何處理 關(guān)閉通道 的問題取決于語言厅缺。有些語言還允許查詢通道狀態(tài)。