一文彻底弄懂 RPC 中的协议和序列化

本文详细探讨了RPC(远程过程调用)中的协议和序列化概念。首先,介绍了协议的作用,包括为何需要协议来标识消息边界,以及为何RPC不直接使用HTTP协议。接着,讲解了协议的设计,包括定长和可扩展协议的设计,以及在RPC中如何处理协议升级。此外,文章还讨论了序列化的重要性,对比了JDK原生序列化、JSON、Hessian和Protobuf等不同序列化方案的优缺点,并提供了在RPC框架中选择序列化方式的建议。最后,文章提到了使用RPC时需要注意的问题,如避免对象构造过于复杂、过大,以及使用不支持的类作为参数等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一文彻底弄懂 RPC 中的协议和序列化

一、协议

协议的作用

我们知道 RPC 需要将对象序列化成二进制数据,写入本地 Socket 中,然后被网卡发送到网络设备中进行网络传输。但是在传输过程中,RPC 并不会把请求参数的所有二进制数据整体一下子发送到对端机器上,中间可能会拆分成好几个数据包,也可能会合并其他请求的数据包(同一个 TCP 连接上的数据),至于怎么拆分合并,这其中的细节会涉及到系统参数配置和 TCP 窗口大小。对于服务提供方来说,他会从 TCP 通道里面收到很多的二进制数据,那这时候怎么识别出哪些二进制是第一个请求的呢?

所以我们需要对 RPC 传输数据的时候进行“断句”,在应用发送请求的数据包里面加入“句号”,这样接收方应用数据流里面分割出正确的数据,“句号”就相当于是消息的边界,用于标识请求数据的结束位置。于是需要在发送请求的时候定一个边界,在请求收到的时候按照这个设定的边界进行数据分割,避免语义不一致的事情发生,而这个边界语义的表达,就是所谓的协议。

协议的设计

我们知道协议的作用之后怎么设计一个协议呢?或者说为啥不直接使用现有的 HTTP 协议呢?

相对于 HTTP 的用处,RPC 给更多的是负责应用间的通信,所以性能要求更高。但是 HTTP 协议的数据包大小相对于请求数据本身要大很多,有需要加入很多无用的内容,比如换行符号、回车符等等;还有一个重要的原因就是 HTTP 协议属于无状态协议,客户端无法对请求和响应进行关联,每次请求都需要重新建立连接,响应完之后再关闭连接。所以对于要求高性能的 RPC 来说,HTTP 协议很难满足需求,RPC 会选择设计更紧凑的私有协议。

上面我们说了需要对传输的数据进行“断句”来确定消息边界,由于 RPC 每次发请求的大小都是不固定的,所以我们的协议必须能让接收方正确的读出不定长的内容。可以固定一个长度(比如4字节)用来保存请求数据大小,这样接收到数据的时候,可以先读取固定长度位置里面的值,值的大小就代表协议的长度,接着根据值的大小来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值