本文通過(guò)gRPC的結(jié)構(gòu)概述和生命周期介紹一些gRPC理念的關(guān)鍵點(diǎn)浮庐。
概述
服務(wù)定義
就像很多RPC系統(tǒng)一樣弹惦,gRPC也是基于定義一個(gè)服務(wù)的想法矿卑,指定可以被遠(yuǎn)程調(diào)用的方法喉恋。默認(rèn)地,gRPC使用protocol buffers作為接口定義語(yǔ)言 (IDL)來(lái)描述服務(wù)接口和預(yù)加載信息的結(jié)構(gòu)母廷。也可能使用其他替代轻黑。
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
gRPC可以定義四種服務(wù)方法:
- Unary RPCs。比如客戶端向服務(wù)端發(fā)送一個(gè)請(qǐng)求琴昆,然后得到一個(gè)返回氓鄙,就像普通的方法調(diào)用:
rpc SayHello(HelloRequest) returns (HelloResponse){
}
- Server streaming RPCs,比如客戶端發(fā)送請(qǐng)求到服務(wù)端业舍,然后得到一個(gè)stream讀取按序返回的messages抖拦。客戶端從返回的stream里讀取直到?jīng)]有消息舷暮。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
}
- Client streaming RPCs态罪,比如客戶端寫(xiě)入一個(gè)序列的消息,然后發(fā)送到服務(wù)端脚牍,然后繼續(xù)使用提供的stream向臀。當(dāng)客戶端結(jié)束寫(xiě)入消息后,就會(huì)等待服務(wù)端讀取后返回?cái)?shù)據(jù)诸狭。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
}
- 雙向streaming RPCs,客戶端和服務(wù)端都發(fā)送信息并且讀-寫(xiě)流君纫。兩個(gè)streams獨(dú)立操作驯遇,所以客戶端和服務(wù)端可以按照他們想要的讀取和寫(xiě)入:比如,服務(wù)端可以接收所有的客戶端消息再返回?cái)?shù)據(jù)或者可以先讀取然后寫(xiě)數(shù)據(jù)蓄髓,或者其他的讀寫(xiě)組合方式叉庐,每個(gè)stream的消息順序都已經(jīng)保存了。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
}
我們?cè)诮酉聛?lái)的章節(jié)里查看這些不同類(lèi)型的RPC的詳情会喝。
使用API層
從定義服務(wù)的.proto文件開(kāi)始陡叠,gRPC提供protocol buffer編譯插件生成客戶端和服務(wù)端的代碼。gRPC用戶在客戶端調(diào)用這些APIs肢执,在服務(wù)端實(shí)現(xiàn)相應(yīng)的API枉阵。
- 在服務(wù)端,服務(wù)器實(shí)現(xiàn)通過(guò)service定義的方法预茄,并且運(yùn)行一個(gè)gRPC服務(wù)來(lái)處理客戶端調(diào)用兴溜。gRPC設(shè)施解碼請(qǐng)求,執(zhí)行service方法,然后encode service response.
- 在客戶端拙徽,客戶端有一個(gè)已知的本地對(duì)象存根(stub)(對(duì)于一些語(yǔ)言刨沦,首選項(xiàng)是客戶端)實(shí)現(xiàn)和服務(wù)端相同的方法”炫拢客戶端就可以在本地對(duì)象上調(diào)用這些方法想诅,為調(diào)用在合適的protocol buffer message類(lèi)型包裝參數(shù) - gRPC隨后發(fā)送請(qǐng)求到服務(wù)端然后返回服務(wù)端的protocol buffer response(s)。
異步 vs. 同步
同步RPC調(diào)用會(huì)阻塞岛心,直到服務(wù)端有返回是最接近RPC的請(qǐng)求過(guò)程的抽象来破。另一方面,網(wǎng)絡(luò)本質(zhì)上是異步的鹉梨,并且在很多場(chǎng)景讳癌,它對(duì)在當(dāng)前線程啟動(dòng)無(wú)阻塞的RPCs很有用。
gRPC編程在大多數(shù)語(yǔ)言里都有同步和異步存皂∩卫ぃ可以在每個(gè)語(yǔ)言里的指南里和相關(guān)文檔查看更多。
RPC生命周期
現(xiàn)在我們來(lái)看看當(dāng)gRPC客戶端調(diào)用gRPC服務(wù)單方法是發(fā)生了什么旦袋。我們不會(huì)看實(shí)現(xiàn)細(xì)節(jié)骤菠,你可以在特定語(yǔ)言頁(yè)里查看更多。
Unary RPC
首先我們來(lái)看最簡(jiǎn)單的RPC類(lèi)型疤孕,客戶端發(fā)送一個(gè)請(qǐng)求并得到一個(gè)回復(fù)商乎。
- 一旦客戶端調(diào)用方法在stub/client對(duì)象上,服務(wù)端會(huì)被通知到RPC被調(diào)用帶著客戶端的metadata, 方法名稱(chēng)祭阀,特定的deadline如果匹配.
- 服務(wù)端然后可以直接返回它的最初的metadata(必須在返回前發(fā)送)鹉戚,或者等待客戶端的請(qǐng)求信息 - 一個(gè)首先發(fā)生的application-specific。
- 一旦服務(wù)端有客戶端的請(qǐng)求信息专控,創(chuàng)建和填充它的response是必須的抹凳。response然后被返回(如果成功)到客戶端帶著狀態(tài)詳情(狀態(tài)碼和可選的狀態(tài)信息)和可選的trailing metadata.
- 如果狀態(tài)是OK的,客戶端會(huì)得到響應(yīng)伦腐,客戶端的請(qǐng)求就完成了赢底。
Server streaming RPC
server-streaming RPC和我們簡(jiǎn)單的例子相似,除了服務(wù)端發(fā)送返回一連串的響應(yīng)在得到客戶端的請(qǐng)求信息后柏蘑。在發(fā)送返回了所有的響應(yīng)后幸冻,服務(wù)端的狀態(tài)詳情(狀態(tài)碼和可選的狀態(tài)信息)和可選的trailing metadata會(huì)被發(fā)送回完成在客戶端】确伲客戶端在得到所有客戶端的相應(yīng)后完成洽损。
Client streaming RPC
client-streaming RPC也和簡(jiǎn)單的例子相同,除了客戶端發(fā)送了一系列的請(qǐng)求到客戶端而不是單個(gè)請(qǐng)求黔攒。服務(wù)端返回單個(gè)對(duì)象趁啸,通常但不一定收到了所有客戶的請(qǐng)求后,連同其狀態(tài)的細(xì)節(jié)和可選的元數(shù)據(jù)强缘。
Bidirectional streaming RPC
在雙向流的RPC里,還是客戶端調(diào)用方法然后服務(wù)端接收客戶端metaata不傅,方法名稱(chēng)和deadline旅掂。然后服務(wù)端可以選擇返回最初的metadata或者等待客戶端開(kāi)始發(fā)送請(qǐng)求。
接下來(lái)的情況就取決于應(yīng)用了访娶,客戶端和服務(wù)端都能在任何順序里讀和寫(xiě)商虐。流操作完全是獨(dú)立的。所以崖疤,比如秘车,服務(wù)端在寫(xiě)回響應(yīng)時(shí)可以等待直到獲取到所有客戶端的信息,或者服務(wù)端和客戶端可以像“乒乓”一樣:服務(wù)端獲取請(qǐng)求劫哼,然后返回響應(yīng)叮趴,然后客戶端基于返回發(fā)送另一個(gè)請(qǐng)求,等等权烧。
Deadlines/Timeouts
gRPC允許客戶端為一個(gè)RPC完成指定超時(shí)時(shí)間眯亦,不然RPC會(huì)被終止,拋出DEADLINE_EXCEEDED錯(cuò)誤般码。在服務(wù)端妻率,可以查看特定的RPC是否超時(shí),或者還剩下多少時(shí)間完成RPC板祝。
如何設(shè)置deadline或者timeout取決與不同的語(yǔ)言宫静,比如,不是所有的語(yǔ)言有默認(rèn)的deadline券时,有些語(yǔ)言APIs依據(jù)deadline(距離上次時(shí)間的點(diǎn))孤里,一些依據(jù)timeout(間隔)。
RPC termination
在gRPC里橘洞,客戶端和服務(wù)端是獨(dú)立的扭粱,并且本地決定請(qǐng)求的成功,但是結(jié)論可能不匹配震檩。這意味,比如蜓堕,你可能有一個(gè)RPC在服務(wù)端成功的完成了("我已經(jīng)發(fā)送了所有的響應(yīng)")但是客戶端失敗了(“返回在我的deadline之后”)抛虏。當(dāng)然服務(wù)端也可能在客戶端發(fā)送所有請(qǐng)求前完成。
Cancelling RPCs
不管是客戶端還是服務(wù)端都可以隨時(shí)取消RPC套才。取消會(huì)立即終止RPC迂猴,首頁(yè)不會(huì)再工作。這不是“撤銷(xiāo)”: 在取消前已經(jīng)發(fā)生的改變不會(huì)被回滾背伴。
Metadata
Metadata是特定RPC請(qǐng)求的信息(比如authentication details)以列表信息的鍵值對(duì)沸毁,鍵是strings,values通常也是strings(但也可以是binary data)峰髓。Metadata對(duì)于gRPC是透明的 - 它可以讓客戶端提供調(diào)用信息到服務(wù)器,或者相反息尺。訪問(wèn)metadata取決于語(yǔ)言携兵。
Channels
gRPC channels在指定的host和port提供連接到gRPC,在創(chuàng)建客戶端存根的時(shí)候使用搂誉⌒旖簦客戶端可以指定特定的channel參數(shù)修改gRPC的默認(rèn)行為,比如切換開(kāi)和關(guān)消息壓縮炭懊。channel有狀態(tài)并级,包含connected和idle。
gRPC如何處理關(guān)閉channel看編程語(yǔ)言侮腹。一些語(yǔ)言也允許查詢channel狀態(tài)嘲碧。