编解码框架

编解码框架教程

Netty 是基于 Java 语言开发的一套开源框架,Java 语言自带的序列化和反序列化机制就可以进行网络数据传输。除了自身携带的序列化和反序列化机制,业界有一些主流的框架,比如:Google 的 Protobuf,Facebook 的 Thrift 和 JBoss Marshalling 等。

JDK序列化和反序列化

对于 Java 开发者来说,JDK 的序列化和反序列化的学习成本是比较低的,但是它只支持 Java 语言,没有办法跨语言。我们都知道,现在只要稍微规模大一点的公司,他们不同的部门,有可能用的编码语言不一样,那么在进行跨语言交互的时候就不合适了。

Java 语言的序列化后的码流太大了,太占带宽,而且它的序列化和反序列化的性能比较低,所以很少有人用 java 自带的序列化和反序列化机制来进行编解码。

Protobuf

Protobuf 的全称是 Google Protobuf Buffers,它是由谷歌开源而来的。它的文件以 .proto 结尾。通过代码生成器我们可以生成对应语言的 POJO 对象和 Protobuf 相关的方法和属性。它是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可以用于数据通信协议、数据存储。

特点

  • 语言无关,平台无关。它支持 Java、C++Python 等多种语言,支持多个平台。
  • 高效的编解码性能,它比 XML 更小(3 ~ 10 倍) ,更快(20~100 倍),更简单。
  • 扩展性、兼容性好。我们可以更新数据结构,它不会影响和破坏原有的旧数据结构。

优点

  • 文本化的数据结构描述语言,可以实现语言和平台无关,特别适合异构系统间的集成。
  • 通过标识字段的书按需,可以实现协议的向前兼容。
  • 自动代码生成,不需要手工编写同样数据结构的 C++ 和 Java 版本。可以通过代码编辑器自动生成相应的对象。
  • 方便后续的管理和维护。相比于代码,结构化的文档更容易维护和管理。

下面是 protobuf 和其它序列化框架性能对比图:

01 protobuf 响应时间对比.png

Protobuf 和其他几种序列化框架的字节数对比:

02 protobuf 和其他序列化框架字节数对比.png

Thrift

Thrift 源于 Facebook。它是一种接口描述语言和二进制通讯协议,被用来定义和创建跨语言的服务。被当作一个远程过程调用(RPC)框架来使用。它当初是由 FaceBook 用来解决内部各个系统间大量数据传输通信以及系统之间语言环境不同需要跨平台的问题。所以 Thrift 是支持多种语言的。

在多种不同的语言之间通信,Thrift 可以作为高性能的通信中间件使用,它支持数据(对象)序列化和多种类型的 RPC 服务。Thrift 适用于静态的数据交换,需要先确定好它的数据结构,当数据结构发生变化时,必须重新编辑 IDL 文件,生成代码和编译,这一点跟其他 IDL 工具相比可以视为是 Thrift 的弱项。Thrift 适用于搭建大型数据交换及存储的通用工具,对于大型系统中的内部数据传输,相对于JSON 和XML 在性能和传输大小上都有明显的优势。

Thrift组成部分

  • 语言系统以及 IDL 编译器:负责由用户给定的 IDL 文件生成相应语言的接口代码。
  • TProtocol:RPC 的协议层,可以选择多种不同的对象序列化方式,如 JSON 和 Binary。
  • TTransport:RPC 的传输层,同样可以选择不同的传输层实现,如 socket、NIO、MemoryBuffer等。
  • TProcessor:作为协议层和用户提供的服务实现之间的纽带,负贵调用服务实现
    的接口;
  • TServer:聚合 TProtocol、TTransport 和 TProcessor 等对象。

Thrift创建

虽然 Thrift 是由 C++ 语言编写的,但可以为众多语言创建代码。要创建一个 Thrift 服务,必须写一些Thrift 文件来描述它,然后通过相应语言的 IDL 为目标语言生成代码,并且写一些代码来启动服务器及从客户端调用它。

JBoss Marshalling

JBoss Marshalling 是一个 Java 对象序列化包,对 JDK 默认的序列化框架进行了优化,但又保持与 Serializable 接口的兼容,同时增加了一些可调用的参数和附加的属性,这些参数可通过工厂类进行配置。

与传统的 Java 序列化机制相比,它的优点如下:

  • 可插拔的类解析器, 提供更加便捷的类加载定制策略,通过一个接口即可实现
    定制。
  • 可插拔的对象替换技术,不需要通过继承的方式。
  • 可插拔的预定义 类缓存表,可以减小序列化的字节数组长度,提升常用类型的对象序列化性能。
  • 无须实 现java.io.Serializable接口,即可实现Java序列化。
  • 通过缓存技 术提升对象的序列化性能。

它主要是在 JBoss 内部使用,应用的范围有限,没有上面两种框架使用范围广。

编解码框架总结

编解码其实就是对数据对象进行序列化和反序列化,在网络中进行传输。而 Java 自带的序列化机制不能跨语言,而且占用比较大的带宽,所以一般不会使用。Protobuf 和 Thrift 是使用率比较高,并且支持跨语言的框架。