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