gRPC 為什么這么快?你知道嗎?
RPC(Remote Procedural Call, 遠(yuǎn)程過程調(diào)用)之所以被稱為 remote,因?yàn)樵谖⒎?wù)架構(gòu)下,RPC 可以實(shí)現(xiàn)遠(yuǎn)程服務(wù)之間的通信。從服務(wù)調(diào)用者的角度來看,它就像一個(gè)本地函數(shù)調(diào)用。
下圖說明了 gRPC 的數(shù)據(jù)流。
圖片
- 步驟 1:客戶前端發(fā)出 REST 調(diào)用。請(qǐng)求體通常為 JSON 格式。
- 步驟 2-4:訂單服務(wù)(gRPC 客戶端)接收 REST 調(diào)用,對(duì)其進(jìn)行轉(zhuǎn)換,然后向支付服務(wù)發(fā)出 RPC 調(diào)用。gPRC 將 client stub 編碼為二進(jìn)制格式,并將其發(fā)送到底層傳輸層。
- 步驟 5:gRPC 通過 HTTP2 在網(wǎng)絡(luò)上發(fā)送數(shù)據(jù)包。由于采用了二進(jìn)制編碼和網(wǎng)絡(luò)優(yōu)化,gRPC 據(jù)說比 JSON 快 5 倍。
- 步驟 6 - 8:支付服務(wù)(gRPC 服務(wù)器)接收來自網(wǎng)絡(luò)的數(shù)據(jù)包,解碼后調(diào)用服務(wù)器應(yīng)用程序。
- 步驟 9 - 11:結(jié)果從服務(wù)器應(yīng)用程序返回,經(jīng)過編碼后發(fā)送到傳輸層。
- 步驟 12 - 14:訂單服務(wù)接收數(shù)據(jù)包、解碼并將結(jié)果發(fā)送給客戶端應(yīng)用程序。
和廣泛用于前后端通信的 REST 相比,gRPC 普遍用于服務(wù)間通信。并且,REST 不是一個(gè)協(xié)議,它只是一個(gè)基于 HTTP 協(xié)議的設(shè)計(jì)范式。gRPC 針對(duì)傳輸層和數(shù)據(jù)編解碼都進(jìn)行了優(yōu)化,使得它的效率更高。
雖然 RPC 調(diào)用在微服務(wù)中被廣泛采用,神書 DDIA (Designing Data-Intensive Applications) 中列舉了一些 RPC 的局限性:
- 本地函數(shù)調(diào)用的結(jié)果是可預(yù)測的,而 RPC 需要經(jīng)過網(wǎng)絡(luò)傳輸,數(shù)據(jù)在中途可能因?yàn)楦鞣N原因丟失。
- RPC 調(diào)用有可能超時(shí),編寫程序時(shí)需要考慮該情況。
- 重試一個(gè)失敗的 RPC 調(diào)用有可能造成數(shù)據(jù)重復(fù),需要考慮冪等。
- 由于傳輸數(shù)據(jù)時(shí)需要序列化和反序列化,RPC 在傳輸復(fù)雜對(duì)象時(shí)會(huì)不太方便。
正是因?yàn)檫@些原因,讓遠(yuǎn)程調(diào)用看上去像是一個(gè)本地調(diào)用的編程思想值得商榷。開發(fā)者在使用 RPC 時(shí)需要有針對(duì)性地進(jìn)行容錯(cuò)處理。