在分布式系统中,RPC尤为重要。SRMP是新生命团队专门为了RPC框架而设计的通信协议,既能覆盖内网高速通信,也能覆盖物联网嵌入式设备。


目标定位

经过十多年实战经验积累以及多方共同讨论,新生命团队(https://github.com/newlifex)制订了一种简单而又具有较好扩展性的RPC(Remote Procedure Call)协议。


全称:简易远程消息交换协议,简称: SRMP(Simple Remote Messaging Protocol)


SRMP主要定位于以下场景:

  • 内网高速通信,大吞吐量(>100万tps)、低延迟(<1ms)
  • 外网远程通信,稳定可靠,海量连接(>10万)
  • 物联网硬件设备,容易简单实现协议


基础格式

协议格式: 1 Flag + 1 Sequence + 2 Length + N Payload

1个字节标识位,标识请求、响应、错误、加密、压缩等;

1个字节序列号,用于请求响应包配对;

2个字节数据长度N,小端字节序,指示后续负载数据长度(不包含头部4个字节),解决粘包问题;

N个字节负载数据,数据内容完全由业务决定,最大长度65534=64k-1。


负载数据大于等于64k时,数据长度字段填65535(0xFFFF),启用后续4字节扩展长度,最大长度4G(0xFFFFFFFF)。

物联网硬件设备建议直接忽略扩展长度。


采用固定2字节表示长度,方便任意语言接入,特别是嵌入式实现,这一点上完胜变长的七位压缩编码整数。内网高速通信可实现8字节头部扩容,而物联网嵌入式设备则可以直接不考虑扩容。

1字节序列号,主要用于UDP通信、串口通信、无线通信等做请求与响应的匹配,这是多路复用的根基所致。


RPC请求与响应

SRMP主要分为请求和响应两种指令。

请求格式

RPC请求封包由4字节头部和数据体部分组成,头部长度位指示了数据体部分总长度。数据体由接口名和请求参数两部分组成,二者都是以压缩长度开始指示数据长度。

如若有扩展需要,可作为请求参数的一部分传输,整体格式不变。例如,某些场景需要Token令牌或者TraceId追踪,实际上可以作为请求参数一部分来整体封包。

请求参数默认采用Json序列化封包,高速接口支持直接以Packet作为参数,绕开序列化的成本开支。强烈建议10000tps以上的接口采用高速Packet传参,此时接口入参只能有一个Packet参数。用户自己对参数进行二进制序列化。

在高并发大吞吐系统中,序列化成本占据整体通信耗时的70%以上,远远超过网络开支。

字节

7

6

5

4

3

2

1

0

1 Flag

请求0

单向

保留

1 Seq

序列号(0~255)

2 Length

数据长度(0~65534)

Body

S 字符串长度

服务接口名称(Action)

N 字节数组长度

请求参数(Json/Packet)


响应格式

RPC响应封包由4字节头部和数据体部分组成,头部长度位指示了数据体部分总长度。数据体由接口名、响应代码、响应数据三部分组成,其中接口名和响应数据以压缩长度开始指示数据长度。响应代码固定4字节整数,0表示成功,部分超场景200也表示成功,其它表示错误码。

如若有扩展需要,可作为响应数据的一部分传输,整体格式不变。

响应数据默认采用Json序列化封包,高速接口支持直接以Packet作为响应数据,绕开序列化的成本开支。强烈建议10000tps以上的接口采用Packet作为响应数据,此时接口返回类型必须是Packet。用户自己对参数进行二进制序列化。

在高并发大吞吐系统中,序列化成本占据整体通信耗时的70%以上,远远超过网络开支。

字节

7

6

5

4

3

2

1

0

1 Flag

响应1

错误

保留

1 Seq

序列号(0~255)

2 Length

数据长度(0~65534)

Body

S 字符串长度

服务接口名称(Action)

4 响应代码(Code)

N 字节数组长度

响应数据(Json/Packet)


总结

SRMP协议采用极为简单的格式实现,便于不同编程语言以及嵌入式硬件设备的接入。

作者:大石头 发布:2021-03-19 12:09:42 浏览:2,030)