高并发下,RPC为什么比HTTP调用更快?

在分布式系统中,RPC(远程过程调用)、和HTTP调用都被广泛使用,下面我详解高并发下,RPC为什么比HTTP调用更快。

协议更轻量,传输开销更小

HTTP是一种通用超文本传输协议,设计初衷是为了支持浏览器与服务器之间的资源访问。

因此它的请求头、响应头以及文本化表达都相对较重。

例如HTTP/1.1请求:

POST /user/get HTTP/1.1
Host: xxx.com
Content-Type: application/json
Content-Length: xxx

{
    "userId":10001
}

里面包含:

请求行
Header
Body

服务端收到以后,还需要进行HTTP协议解析。

相比之下,RPC通常采用更轻量的私有协议或二进制协议,去掉了许多对服务调用并不必要的通用字段。

例如:

请求ID
服务名
方法名
参数
序列化数据

然后直接交给RPC框架处理。

RPC则会尽量压缩协议内容,只保留调用方法、参数和返回值等核心信息。

因此,在相同业务请求下,RPC传输的数据量通常更小,网络耗时也更低。

 

序列化效率更高

这是RPC性能优势中最容易理解的一点。

假设我们调用一个用户服务:

getUser(10001)

如果使用传统HTTP + JSON,可能会传输类似这样的数据:

{
    "userId": 10001,
    "name": "mikechen",
    "age": 30
}

JSON最大的特点是:

可读性很好,但数据冗余比较多。

例如:

"userId"
"name"
"age"

这些字段名称本身也需要进行网络传输。

而很多RPC框架会使用:

Protobuf
Thrift
Hessian
Kryo

等序列化方式。

例如Protobuf会根据预先定义的数据结构进行二进制编码:

message User {
    int64 userId = 1;
    string name = 2;
    int32 age = 3;
}

最终传输的是更加紧凑的二进制数据。

所以整个过程可以理解成:

HTTP + JSON

对象
 ↓
JSON序列化
 ↓
文本数据
 ↓
网络传输
 ↓
JSON反序列化
 ↓
对象

RPC:

对象
 ↓
二进制序列化
 ↓
更小的数据包
 ↓
网络传输
 ↓
二进制反序列化
 ↓
对象

数据量减少之后,网络传输时间和序列化/反序列化成本都会下降。

 

 

连接复用与通信模型更高效

这是RPC性能优化中非常关键的一点。

假设客户端每调用一次服务,都重新建立TCP连接:

Client
  ↓
TCP三次握手
  ↓
发送请求
  ↓
服务器响应
  ↓
关闭连接

一次请求就建立一次连接。

如果QPS非常高,就会产生大量连接建立和关闭的成本。

例如:

10000 QPS

意味着可能产生非常大量的连接操作。

RPC框架通常会维护连接池:

Client
   │
   ├── Connection 1
   ├── Connection 2
   ├── Connection 3
   └── Connection 4
          ↓
       RPC Server

建立连接之后,可以持续发送大量请求:

Connection 1
 ├── Request 1
 ├── Request 2
 ├── Request 3
 ├── Request 4
 └── Request 5

这样就避免了大量重复的,握手和挥手过程,从而在高并发环境下表现得更快、更稳。

以上

评论交流
    说说你的看法