RPC vs HTTP
Remote Procedure Call,远程过程调用)vs HTTP(Hypertext Transfer Protocol,超文本传输协议)
1. 协议复杂性与开销
HTTP
- 基于文本的协议:HTTP 是一种文本协议,所有的数据(包括头部信息和消息体)都以纯文本格式进行传输。这种格式易于人类阅读,但在网络上传输时效率较低。
- 头部冗长:HTTP 请求和响应通常包含大量头部信息,这些头部信息会随每次请求和响应被传输,增加了数据量和网络开销。
- 无状态:HTTP 本质上是无状态的,每次请求都是独立的,服务器并不记得先前的请求。这意味着每次请求都需要重新建立连接(在 HTTP/1.1 中可能会复用连接,但仍有开销)。
RPC
- 高效的二进制协议:RPC 协议(如 gRPC、Thrift、Protobuf 等)通常使用二进制格式来序列化和反序列化数据。二进制格式比文本格式更加紧凑,减少了数据传输的开销。
- 简化的头部信息:RPC 通常只包含必要的元数据,其头部信息相对简洁,减少了数据冗余。
- 方法调用语义:RPC 模拟本地方法调用的语义,调用过程简化为直接的函数调用,减少了通信协议层的复杂性。
纯文本格式 vs 二进制格式
- 数据表示方式
纯文本 JSON:JSON 是一种文本格式,用可读的字符来表示数据。例如,数字、字符串、布尔值等都以字符形式编码。即使数据本身很小,文本格式仍然需要多个字符来表示。例如,整数
123
在 JSON 中表示为"123"
,占用 3 个字节,而布尔值true
需要 4 个字节。二进制 JSON:二进制格式(如 MessagePack、CBOR、BSON)直接使用紧凑的字节表示数据。例如,整数
123
在二进制格式中可能只需要 1-2 个字节存储,而布尔值true
只需要 1 个字节。
- 结构性开销
纯文本 JSON:文本格式通常需要额外的字符来表示数据的结构和层次。例如,JSON 使用花括号
{}
、冒号:
和引号""
来表示对象、键值对和字符串。这些符号虽然便于人类阅读,但增加了数据的体积。二进制 JSON:二进制格式通常通过紧凑的编码来表示结构信息。例如,字段名可以通过字段编号或索引来替代,从而减少冗余字符。数据类型也可以直接用特定字节表示,无需使用额外的字符。
- 举例说明
假设有以下 JSON 数据:
{
"id": 123,
"name": "Alice",
"active": true
}
纯文本 JSON:
"id": 123
:占用8
个字节。"name": "Alice"
:占用15
个字节。"active": true
:占用14
个字节。- 总共:
37
个字节(不包括空格和换行符)。
二进制 JSON(MessagePack 举例):
id: 123
:1-2
个字节存储整数。name: Alice
:6
个字节(1 个字节表示长度,5 个字节表示字符串)。active: true
:1
个字节。- 总共:
8-10
个字节。
2. 连接管理
HTTP
- TCP 连接建立和释放:传统的 HTTP/1.x 每次请求通常需要建立和释放一个 TCP 连接,这会引入较大的延迟(握手过程),尽管 HTTP/1.1 引入了连接复用(keep-alive),但仍需管理连接的生命周期。
- 协议头开销:每次 HTTP 请求都需要发送头信息,而这些头信息的处理和解析会增加服务器和客户端的负载。
RPC
- 长连接:很多 RPC 实现(如 gRPC)使用长连接,通过一个持久的连接来处理多个请求。这减少了连接建立和释放的开销,并降低了网络延迟。
- 多路复用:RPC 框架通常支持多路复用(multiplexing),允许在同一个连接上同时发送多个请求,进一步提高了吞吐量。
3. 序列化与反序列化
HTTP
- 基于 JSON 或 XML:HTTP 通常使用 JSON 或 XML 作为数据格式。这些格式虽然易于人类理解,但解析和构建的代价较高,尤其是当数据量较大时。
- 性能瓶颈:JSON 和 XML 的解析速度相对较慢,而且其数据量(文件体积)相对较大,传输时会带来额外的开销。
RPC
- 高效的序列化机制:RPC 框架一般使用高效的序列化机制,如 Protobuf、Avro 或 MessagePack,这些二进制格式相比 JSON 和 XML 更加紧凑,序列化和反序列化的速度更快。
- 数据格式紧凑:二进制序列化格式减少了传输的数据量,并且由于其紧凑性,解析和处理的效率更高。
4. 处理模型
HTTP
- 请求-响应模型:HTTP 的请求-响应模型相对简单,但每次请求的处理往往需要完整的解析、路由和响应构建过程,这增加了服务器端的处理开销。
- 上下文切换开销:由于 HTTP 协议的无状态性,每个请求可能会引发大量的上下文切换开销。
RPC
- 方法调用模型:RPC 更加贴近本地方法调用,直接传递参数并获取结果。这个模型更加自然,且开销较低。
- 优化的处理路径:RPC 框架通常为高效调用进行了深度优化,减少了请求处理过程中的中间环节,从而提高了性能。
5. 数据传输效率
HTTP
- 重载网络:HTTP 的数据传输需要经过多层协议栈(如 HTTP 头部、TCP/IP 协议),每一层都可能引入额外的开销。
- 冗余数据:HTTP 请求和响应中包含大量冗余的头部信息,随着请求数量的增加,累积的网络带宽消耗也会显著增加。
RPC
- 直接通信:RPC 框架通常直接通过 TCP、QUIC 等高效协议传输数据,减少了不必要的开销。
- 压缩与优化:很多 RPC 实现支持对传输的数据进行压缩,并且会对数据传输路径进行优化,以确保低延迟和高吞吐。