RPC(remote procedure call 遠程過程調用)框架實際是提供了一套機制,使得應用程序之間可以進行通信,而且也遵從server/client模型。使用的時候客戶端調用server端提供的接口就像是調用本地的函數一樣。
既然是server/client模型,那么我們直接用restful api不是也可以滿足嗎,為什么還需要RPC呢?
gRPC vs. Restful API
RPC和restful API都提供了一套通信機制,用於server/client模型通信,而且它們都使用http作為底層的傳輸協議(嚴格地說, gRPC使用的http2.0,而restful api則不一定)。不過gRPC還是有些特有的優勢,如下:
gRPC可以通過protobuf來定義接口,從而可以有更加嚴格的接口約束條件。關於protobuf可以參見筆者之前的小文Google Protobuf簡明教程
另外,通過protobuf可以將數據序列化為二進制編碼,這會大幅減少需要傳輸的數據量,從而大幅提高性能。
gRPC可以方便地支持流式通信(理論上通過http2.0就可以使用streaming模式, 但是通常web服務的restful api似乎很少這么用,通常的流式數據應用如視頻流,一般都會使用專門的協議如HLS,RTMP等,這些就不是我們通常web服務了,而是有專門的服務器應用。)
gRPC 是一個高性能、通用的開源RPC框架,其由 Google 主要面向移動應用開發並基於HTTP/2 協議標准而設計,基於 ProtoBuf(Protocol Buffers) 序列化協議開發,且支持眾多開發語言。本文作者深入研究了 gRPC 協議,對協議本身作出解構。
gRPC 是基於 HTTP/2 協議的。
gRPC使用protocol buffers作為接口描述語言(IDL)以及底層的信息交換格式,一般情況下推薦使用 proto3因為其能夠支持更多的語言,並減少一些兼容性的問題。
HTTP/2 是一個二進制協議,這也就意味着它的可讀性幾乎為 0,但幸運的是,我們還是有很多工具,譬如 Wireshark, 能夠將其解析出來。
在了解 HTTP/2 之前,需要知道一些通用術語:
1、Stream: 一個雙向流,一條連接可以有多個 streams。
2、Message: 也就是邏輯上面的 request,response。
3、Frame::數據傳輸的最小單位。每個 Frame 都屬於一個特定的 stream 或者整個連接。一個 message 可能有多個 frame 組成。
Frame 是 HTTP/2 里面最小的數據傳輸單位,一個 Frame 定義如下(直接從官網 copy 的):
4、Flag 和 R:保留位,可以先不管。
5、Stream Identifier:標識所屬的 stream,如果為 0,則表示這個 frame 屬於整條連接。
6、Frame Payload:根據不同 Type 有不同的格式。Frame 的格式定義還是非常的簡單,按照官方協議,可以非常方便的寫一個出來。
7、Multiplexing,HTTP/2 通過 stream 支持了連接的多路復用,提高了連接的利用率。Stream 有很多重要特性:
1、一條連接可以包含多個 streams,多個 streams 發送的數據互相不影響。
2、Stream 可以被 client 和 server 單方面或者共享使用。
3、Stream 可以被任意一段關閉。
4、Stream 會確定好發送 frame 的順序,另一端會按照接受到的順序來處理。
5、Stream 用一個唯一 ID 來標識。
1、Stream ID,如果是 client 創建的 stream,ID 就是奇數,如果是 server 創建的,ID 就是偶數。ID 0x00 和 0x01 都有特定的使用場景。
2、Stream ID 不可能被重復使用,如果一條連接上面 ID 分配完了,client 會新建一條連接。而 server 則會給 client 發送一個 GOAWAY frame 強制讓 client 新建一條連接。
參考:深入了解gRPC
相比較而言,Protobuf有如下優點:
- 足夠簡單
- 序列化后體積很小:消息大小只需要XML的1/10 ~ 1/3
- 解析速度快:解析速度比XML快20 ~ 100倍
- 多語言支持
- 更好的兼容性,Protobuf設計的一個原則就是要能夠很好的支持向下或向上兼容