MessagePack是一个高效的二进制序列化框架,它像JSON一样支持不同语言间的数据交互,但是它的性能更快,序列化之后的码流也更小。
由于MessagePack在业界得到了非常广泛的应用,将介绍如何利用Netty的CodeC框架新增对MessagePack的支持。
MessagePack介绍
MessagePack的特点如下:
- 编解码高效,性能高;
- 序列化之后码流小;
- 支持跨语言。
衡量序列化框架通用性的一个重要指标就是对多语言的支持,因为数据交换的双方很难保证一定采用相同的语言开发,如果序列化框架和某种语言绑定,他就很难跨语言,如Java的序列化机制。
MessagePack提供了多种语言支持:Java、Python、Ruby、Haskell、C#、OCaml、Lua、Go、C、C++等。
官网地址:http://msgpack.org/
Git地址:https://github.com/msgpack/msgpack-java
MessagePack Java API 介绍
Maven引用的方式:
API官方示例:
代码清单1 官方示例
MessagePack编码器和解码器开发
MessagePack编码器开发
代码清单2 msgpack编码器 MsgpackEncoder
MsgpackEncoder继承MessageToByteEncoder,它负责将Object类型的POJO对象编码为byte数组,然后写入到ByteBuf中。
MessagePack解码器开发
代码清单3 msgpack编码器 MsgPackDecoder
首先从数据报arg1中获取需要解码的byte数组,然后调用MessagePack的read方法将其反序列化为Object对象,将解码后的对象加入到解码列表中arg2中,这样就完成了MessagePack的解码操作。
#### 功能测试
完成编解码器开发之后,我们以Netty原生Echo程序为例,进行测试。对Echo进行简单改造,传输的对象由字符串修改为POJO对象,利用MessagePack对POJO对象进行序列化。
序列化对象
代码清单4 UserInfo
客户端代码
代码清单5 EchoClient
代码清单6 EchoClientHandler
服务端代码
代码清单7 EchoServer
代码清单8 EchoServerHandler
运行结果分析
没有进行粘包/半包处理,结果分析
不进行处理就是去掉服务端与客户端中如下代码:
客户端运行结果如下。
图1 客户端运行结果
服务端运行结果如下。
图2 服务端运行结果
没有进行粘包/半包的处理,我们开发的MessagePack编解码框架还不能正常工作,如下为粘包场景下测试结果。
图3 粘包场景下测试结果
粘包/半包支持下,运行结果分析
在MessagePack编码器之前添加LengthFieldPrepender,它将在ByteBuf之前添加2个字节的消息长度字段,其原理如图1所示。
图4 LengthFieldPrepender原理示意图
在MessagePack解码器之前添加LengthFieldBaseFrameDecoder,用于处理半包消息,这样后面的MsgpackDecoder接收到的永远是整包消息,它的工作原理如图2所示。
图5 LengthFieldBaseFrameDecoder原理示意图
服务端运行结果如下。
图6 服务端运行结果
客户端运行结果如下。
图7 客户端运行结果