RPC 消息协议设计注意点
一套 RPC 消息协议包括几个基本内容:消息的边界,消息的编码,消息的结构以及压缩算法
消息的边界
RPC 通信中传递的一串由N条消息组成的消息流,如果一条消息的长度过大,会被网络协议栈拆分为多个数据包,如果一条消息的长度过小,网络协议栈会将多条消息合并为一个数据包再发送,所以必须明确每条消息的边界(分隔符), 接收方才能正确的从消息流中解析出一条条的消息
特殊分隔符法
message body | \r\n | message body | \r\n |
---|---|---|---|
特殊分隔符法,很好理解,就是在每条消息最后加一个或几个特殊的字符作为分隔符,比如/r/n ,这种方式有两个要求,第一个就是消息中间不能包含分隔符,第二个就是要求消息的内容尽量是文本消息,它的优点是可读性强,缺点是传输效率不高. |
长度前缀法
length | message body | length | message body |
---|
发送方在每条消息前面加一个固定字节长度的整数值,用于表示消息体的长度,后面紧跟消息体.接收方在读取消息的时候,首先读取到固定字节长度的整数值,然后在读取相应长度的字节数组,就可以完成的读取出一个消息,这种方式很适合用于二进制消息,它的优点是传输效率高,但可读性差.
两种方法的混合
特殊分隔符法和长度前缀法,各有优劣,所以也可以把两者结合使用,扬长避短.比如 HTTP 协议就是这种情况,它的消息头用\r\n
分割符,消息体用通过消息头中的Content-Length
确定长度.接收方根据分隔符法读取消息头,再根据Content-Length
指定的长度读取消息体,消息体可以是文本也可以是二进制数据.
消息的编码
消息的编码有两种选择,二进制或文本.
二进制可读性差,但效率高,文本可读性好,效率相对差一点
消息的结构
协议需要自己拟定消息的结构,客户端和服务端根据这样的结构规则对消息进行序列化和反序列化.
比如在rest架构中用的最多的 json,就是一种常用的消息结构,它的优点是可读性非常好,确定是比较啰嗦,json中大量使用了引号,冒号大括号,且每次传递都要发送一遍key
,这样的冗余就会造成网络传输中流量的浪费,在一些性能要求高的服务中,这样做是不合适的.
在同一条消息通道上,发送方和接收方可以规定好消息格式,传输的时候只传输 value
就可以了,接收方可以根据固定的代码将 value
和 key
一一对应. 这样就可以在传输中只传递值
,不传递结构
, 可以很好的节省流量.
消息压缩
为了减轻网络带宽的压力,对消息进行压缩是行之有效的方法,但是这样会加重 CPU 的负担,所以在决定是否使用压缩算法时要进行权衡.最常见的http协议中,就会在消息头中使用 content-encoding
指定压缩算法.
文章标题:RPC 消息协议设计注意点
文章字数:899
本文作者:Waterandair
发布时间:2018-05-16, 09:24:06
最后更新:2019-12-28, 14:03:59
原始链接:https://waterandair.github.io/2018-05-16-rpc-protocol-basic.html版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。