通過三篇筆記簡單介紹下 gRPC,后續(xù)進(jìn)行代碼實(shí)踐。
gRPC 介紹
gRPC 是一個(gè)高性能、跨平臺(tái)、開源和通用的 RPC 框架,面向移動(dòng)和 HTTP/2 設(shè)計(jì)。
當(dāng)前幾乎所有主流語言都支持 gRPC,在 gRPC 里客戶端應(yīng)用可以像調(diào)用本地方法一樣直接調(diào)用另一臺(tái)機(jī)器上服務(wù)端應(yīng)用的方法。
要使用 gRPC :首先使用接口定義語言(interface definition language, IDL)定義一個(gè)服務(wù),定義能夠被遠(yuǎn)程調(diào)用的方法(包含參數(shù)和返回類型)。借助服務(wù)定義,可以生成服務(wù)端代碼,也就是服務(wù)端骨架(skeleton)和客戶端代碼,即客戶端存根(stub)。這樣客戶端就能夠調(diào)用我們?cè)诜?wù)接口中指定的方法。
服務(wù)定義
gPRC 使用 protocol buffers 作為 IDL 來定義接口,protocol buffers 是語言中立、平臺(tái)無關(guān)、實(shí)現(xiàn)結(jié)構(gòu)化數(shù)據(jù)序列化的可擴(kuò)展機(jī)制。
服務(wù)接口定義在 proto 文件中指定,下面給出一個(gè)使用 protocol buffers 定義服務(wù)的文件。
// protocol buffers版本為 proto3
syntax = "proto3";
// 用來防止協(xié)議消息類型命名沖突的包名,也可用來生成代碼
package helloproto;
// 定義gRPC服務(wù)接口
service Greeter {
// 遠(yuǎn)程調(diào)用方法,可以添加多個(gè)
rpc sayHello(HelloRequest) returns (HelloReply) {}
}
// 定義 HelloRequest 的消息格式
message HelloRequest {
string name = 1;
string description =2;
}
// 定義 HelloReply 的消息格式
message HelloReply {
string value = 1;
}
服務(wù)就是一組可以被遠(yuǎn)程調(diào)用的方法,其輸入?yún)?shù)和返回參數(shù)可以是用戶定義類型(例如我們的示例),也可以是 protocol buffers 中的類型,它們被構(gòu)造成消息。消息中包含一系列的字段,每個(gè)字段有唯一的編號(hào)。
消息傳輸
在調(diào)用 gRPC 服務(wù)時(shí),客戶端會(huì)將 RPC 請(qǐng)求封裝(marshal)為 protocol buffers 格式,然后將其通過 HTTP/2 進(jìn)行發(fā)送。服務(wù)端接收到請(qǐng)求后會(huì)解析(unmarshal),對(duì)應(yīng)的過程調(diào)用同樣使用 protocol buffers 執(zhí)行,然后遵循與請(qǐng)求類似的流程返回響應(yīng)報(bào)文。
gRPC 通信模式
gRPC 主要包含四種通信模式:
簡單/一元RPC模式(Simple RPC)??蛻舳税l(fā)起請(qǐng)求,然后等待服務(wù)端響應(yīng)。
服務(wù)端流RPC模式(Server-side streaming RPC)。客戶端發(fā)起一次請(qǐng)求,服務(wù)端可以連續(xù)返回?cái)?shù)據(jù)流。
客戶端流RPC模式(Client-side streaming RPC)。與服務(wù)端數(shù)據(jù)流模式相反,客戶端持續(xù)向服務(wù)端發(fā)送數(shù)據(jù)流,在發(fā)送結(jié)束后,由服務(wù)端返回一個(gè)響應(yīng)。
雙向流RPC模式(Bidirectional streaming RPC)、客戶端和服務(wù)端都可以向?qū)Ψ桨l(fā)送數(shù)據(jù)流。
gRPC的特點(diǎn)
gRPC優(yōu)勢(shì)
gRPC 越來越受歡迎,是因?yàn)樗兄恍╆P(guān)鍵的優(yōu)勢(shì)。
提供高效的進(jìn)程間通信。 gRPC 使用的 protocol buffers 是二進(jìn)制協(xié)議,相比傳統(tǒng)的 JSON 和 XML這樣的文本化格式,效率高很多,另外,gRPC基于 HTTP/2,也使它成為最高效的通信技術(shù)之一。
具有簡單且定義良好的服務(wù)接口和模式。 gROC為應(yīng)用程序開發(fā)提供了一種契約優(yōu)先的方式。即首先定義服務(wù)接口,然后去處理實(shí)現(xiàn)細(xì)節(jié)。因此,相比 RESTful 服務(wù)定義中的 OpenAPI/Swagger 和 Web Service 中的WSDL,gRPC提供了簡單一直、可靠可擴(kuò)展的應(yīng)用程序開發(fā)體驗(yàn)。
屬于強(qiáng)類型。 gRPC 使用 protocol buffers 清晰定義了應(yīng)用程序間通信所使用類型,可以減少跨團(tuán)隊(duì)合作時(shí)的運(yùn)行時(shí)錯(cuò)誤和互操作錯(cuò)誤,使分布式應(yīng)用程序的開發(fā)更加穩(wěn)定。
支持多語言。 protocol buffers 是語言中立的,可以支持任意語言與現(xiàn)有的 gRPC 服務(wù)器或客戶端進(jìn)行互操作。
支持雙工流。 gRPC在客戶端和服務(wù)端都提供了對(duì)流的原生支持,這些功能都被整合到了服務(wù)定義本身之中。
內(nèi)置很多高級(jí)特性。 gRPC 內(nèi)置了很多高級(jí)特性,如認(rèn)證、加密、彈性、元數(shù)據(jù)交換、壓縮、負(fù)載均衡、服務(wù)發(fā)現(xiàn)等。
與云原生生態(tài)系統(tǒng)進(jìn)行了集成。 gRPC 是 CNCF 的一部分,云上很多框架合和技術(shù)對(duì) gRPC 提供原生支持,比如 Envoy,就使用 gRPC作為通信協(xié)議。
已經(jīng)發(fā)展成熟并被廣泛使用。 gRPC已發(fā)展成熟,很多大型科技公司都采用了 gRPC,比如Square、Lyft、Netflix等。
gRPC劣勢(shì)
當(dāng)然,gRPC也存在著一些劣勢(shì):
gRPC可能不太適合面向外部的服務(wù)。如果希望給將應(yīng)用程序或服務(wù)通過互聯(lián)網(wǎng)暴露給外部客戶端,gRPC可能不是最合適的協(xié)議。gRPC服務(wù)具有契約驅(qū)動(dòng)、強(qiáng)類型的特點(diǎn),這可能會(huì)限制我們向外暴露服務(wù)的靈活性,同時(shí)消費(fèi)者的控制權(quán)會(huì)削弱很多。gRPC網(wǎng)關(guān)可以解決此問題。
巨大的服務(wù)定義變更是復(fù)雜的開發(fā)流程。如果出現(xiàn)巨大的 gRPC 服務(wù)定義變更,通常需要重新生成客戶端代碼和服務(wù)端代碼。當(dāng)然大多數(shù) gRPC 服務(wù)定義的變更可以在不破壞服務(wù)契約的情況下完成,而且只要不引入破壞性變更,gRPC 就可以與不同版本的 proto 客戶端和服務(wù)器進(jìn)行交互。
gRPC生態(tài)系統(tǒng)相對(duì)較小。 與傳統(tǒng)的REST相比,gRPC的生態(tài)系統(tǒng)依然相對(duì)較小。瀏覽器和移動(dòng)端應(yīng)用程序?qū)?gRPC 的支持依舊處于初級(jí)階段。