# 《RPC手撸专栏》第6章:自定义网络传输协议的实现

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

大家好,我是冰河~~

RPC框架作为分布式系统底层通信的基础设施框架,远程过程通信没有网络传输协议怎么行?

# 一、前言

RPC框架要如何才能轻松拿捏自定义网络协议?

RPC作为分布式系统底层通信的基础设施框架,最主要的功能就是进行远程过程调用,这种调用方式不用想,肯定会涉及到网络传输。通常情况中,只要是涉及到数据在网络过程中传输,都是要通过某种协议进行的。例如HTTP协议、TPC协议、UDP协议这种。

数据由发送方发送到接收方之前,会通过某种协议将其编码成二进制流,通过网络将二进制流传输到接收方后,会根据协议将其解码成对应的数据。当接收方处理完数据返回结果前,也需要先通过协议将返回的数据编码成二进制流,通过网络传输到发送方后,根据协议将二进制数据解码成对应的数据。整个过程如图6-1所示。

图6-1 数据在发送方与接收方之间的传输过程

由图6-1可以看出,网络协议在整个网络通信过程中是至关重要的,是数据进行编解码的依据。

说的直白点,就好比两个打电话的人,比如张三给李四打电话,三张好比是数据的发送方,李四好比是数据的接收方。张三给李四打电话,李四接通电话后,二者就建立了连接。张三与李四通话的过程中,不管是三张说话还是李四说话,说话的语音信息在网络中传输之前,都会先将语音信息根据通话协议编码成二进制流,传输到对方后,再根据通话协议将二进制流解码成语音信息。如图6-2所示。

图6-2 张三与李四的通话过程

可以看到,数据在网络传输的过程中是需要通过某种协议进行编码和解码的。

# 二、目标

bhrpc框架的数据交互需要实现自定义网络传输协议,这个目标如何实现?

在前面的章节中,我们实现了bhrpc框架服务提供者收发消息的基础功能,使用了Netty自带的编码器StringEncoder和Netty自带的解码器StringDecoder。也就是在之前的章节中,系统终端和服务提供者之间传输数据时使用的是Netty自带的封装好的协议。但是,Netty本身封装好的协议对于实现RPC框架来说,无论是协议的定制化方面,还是后期对于性能调优方面,都会是一个性能瓶颈点。

所以,在实现bhrpc框架的过程中,需要我们自己实现自定义的网络传输协议,在自定义的网络传输协议的实现中,我们可以加入一些框架中特有的信息、也可以根据具体需要自定义网络传输协议的格式、长度等信息,甚至可以在自定义的网络传输协议中根据具体需要添加一些预留字段,以方便后期扩展。

说干就干,接下来,我们就一起设计和实现自定义的网络传输协议。

# 三、设计

如果是让你设计网络传输协议,你会怎么设计呢?

一般情况下,网络传输协议的设计可以包含消息头和消息体两部分,如图6-3所示。

图6-3 通用网络传输协议结构

  • 一个完整的网络传输协议可以分为消息头和消息体。
  • 消息头中主要存放的是一些对应整个消息的定义信息,比如协议的类型、状态、消息id、消息的长度等等信息。
  • 消息体中主要存放的就是具体的传输数据。

我们可以按照这个网络传输协议的通用逻辑来设计自定义网络传输协议,同样,bhrpc框架的网络传输协议也会分为消息头和消息体两部分,并且会根据具体的需要,暂时将消息头部分的长度定义为32字节,具体如图6-4所示。

图6-4 自定义协议的实现

可以看到,在自定义的网络传输协议中,也会将整个协议分为消息头和消息体两部分。

  • 消息头总共32字节,会分为魔数、报文类型、状态、消息ID、序列化类型和数据长度。
  • 消息体就是要传输的具体数据。

其中,消息头中的各个字段含义如下:

  • 魔数:验证自定义网络传输协议的最基本的校验信息,占据2字节空间。
  • 报文类型:消息的类型,可以分为请求消息、响应消息和心跳消息,占据1字节空间。
  • 状态:消息的状态,占据1字节空间。
  • 消息ID:消息的唯一标识,占据8字节空间。
  • 序列化类型:数据进行序列化和反序列化的类型标识,暂定16字节空间。
  • 数据长度:标识消息体的数据长度,占据4字节空间。

# 四、实现

说了这么多,自定义网络协议该怎么实现呢?

# 1.工程结构

  • bhrpc-annotation:实现bhrpc框架的核心注解工程。
  • bhrpc-common:实现bhrpc框架的通用工具类,包含服务提供者注解与服务消费者注解的扫描器。
  • bhrpc-constants:存放实现bhrpc框架通用的常量类。
  • bhrpc-protocol:实现bhrpc框架的自定义网络传输协议的工程。
  • bhrpc-provider:服务提供者父工程。
    • bhrpc-provider-common:服务提供者通用工程。
    • bhrpc-provider-native:以纯Java方式启动bhrpc框架的工程。
  • bhrpc-test:测试bhrpc框架的父工程。
    • bhrpc-test-provider:测试服务提供者的工程。
    • bhrpc-test-scanner:测试扫描器的工程。

工程源码: 关注冰 冰河技术 微信公众号,回复 bhrpc, 获取代码链接地址。

# 2.核心实现类关系

核心实现类的关系如图6-5所示。

图6-5 核心实现类的关系

由图6-5可以看出,自定义网络传输协议主要由7个类组成,分别是RpcType、RpcMessage、RpcRequest、RpcResponse、RpcHeader、RpcHeaderFactory和RpcProtocol。

# 查看完整文章

加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码