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设计的一个原则就是要能够很好的支持向下或向上兼容