Java 序列化与主流编解码技术框架介绍

目录

Java 序列化缺陷

Google · Protobuf  编解码

Facebook · Thrift 编解码

Jboos · Marshaling 编解码

MessagePack 编解码


序言

1、本文将主要介绍:1)Java 序列化的缺点,2)业界流行的编解码技术框架介绍。

2、介绍编解码技术之前,就不得不提 Java 序列化,特别提醒:Java 序列化只是 Java 编解码技术中的其中一种!

3、Java 序列化的目的主要有两点:

     1)网络传输

     2)对象持久化

4、基于 Java 提供的对象输入/输出流 ObjectInputStream 和 ObjectOutputStream ,可以直接把 Java 对象作为可存储的字节数组写入文件,也可以在网络上传输。这对于程序员来说,通过基于 JDK 默认的序列化机制可以避免操作底层的字节数组,从而提升开发效率。

5、网络传输时,需要把传输的 Java 对象编码为字节数组或者 ByteBuffer 对象,而当远程服务读取到 ByteBuffer 对象或者字节数组时,需要再将其解码成发送时的 Java 对象,这就称为 Java 对象编解码技术。

Java 序列化缺陷

1、Java 序列化从 JDK1.1 版本就已经提供,它不需要添加额外的类库,最简单的方式只需要实现 java.io.Serizlizable 接口即可。 可以参考《Java 序列化漏洞多到修不完》、《Java 内置序列化三种方式

1)无法跨语言传输

无法跨语言是 Java 序列化最致命的问题。对于跨进程的服务调用,服务提供者可能会使用 C++ 等其它语言开发,而当需要和异构语言进程交互时,Java 序列化就难以胜任。
由于 Java 序列化技术是 Java 语言内部的私有协议,其它语言并不支持,对于用户来说它完全是黑盒。Java 序列化后的字节数组,别的语言无法进行反序列化,这就严重阻碍了它的应用。
目前市场上流行的 Java RCP(远程服务调用)通信框架,都没有使用 Java 序列化作为编解码框架,原因就是它无法跨语言。

2)序列化后码流过大评价一个编解码框架的优劣时,往往会考虑以下因素:
** 是否支持跨语言,支持的语言种类是否丰富
** 编码后的码流大小
** 编解码的性能
** 类库是否小巧,API 使用是否方便
** 使用者需要手工开发的工作量和难度
同等情况下,编码后的字节数组越大,存储的空间就越大,硬盘成本就越高,网络传输时越占宽带,导致系统的吞吐量降低。Java 序列化后的码流偏大也一直被业界所诟病,导致应用范围受到了很大限制。
3)序列化性能太低比如相比其它方式,同样是序列化 100万次,Java 序列化耗费时间长。

主流编解码框架

1、Java 序列化仅仅是 Java 编解码技术的一种,由于它的种种缺陷,于是业界开发出了多种性能更优秀的编解码技术框架,本文会选择其中主流编解码技术框架进行介绍。

2、编解码框架同样也是序列化,从网络通信层面来说,它主要目的也是为了直接传递对象,即先将对象序列化,然后网络传输到目的地,接收方再进行反序列化生成对象。

3、实际应用中,是否序列化对象进行传递还是应该根据需求而定,有时候发送字符串也是挺方便的,比如一个 POJO 对象,或者 Map、List 等,可以先使用 Gson、FastJson 等库将对象序列化为 Json 字符串,然后发送 json 字符串数据,接收的时候,再用 Gson、FastJson 反序列化,将 json 字符串转为对象即可。

Google · Protobuf  编解码

1、Protobuf 全称 Google Protocol Buffers,由谷歌开源而来,在谷歌内部久经考验。它将数据结构以 .proto 文件进行描述,通过代码生成工具可以生成对应数据结构的 POJO 对象和 Protobuf 相关的属性和方法。

2、Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化。它很适合做数据存储或 RPC 数据交换。

3、Protobuf 在 Github 开源地址https://github.com/protocolbuffers/protobuf

     Protobuf supports several different programming languages. For each programming language, you can find instructions in the corresponding source directory about how to install protobuf runtime for that specific language:

4、Protobuf 另一个吸引人的是它的数据描述文件和代码生成机制。利用数据描述文件对数据结构进行说明,其优点如下:

1)文本话的数据结构描述语言,可以实现语言和平台无关,特别适合异构系统间的集成

2)通过标识字段的顺序,可以实现协议的前后兼容

3)字段代码生成,不需要手工编写同样数据结构的 C++ 和 Java 版本

4)方便后续的管理和维护,相比于代码,结构化的文档更易管理和维护

Facebook · Thrift 编解码

1、Thrift 源于 Facebook,创建的目的是为了解决 Facebook 各系统间大数据量的传输通信问题,满足系统之间语言环境不同的需求。Thrift 可以支持多种程序语言:

     The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.

2、2007 年 Facebook 将 Thrift 作为一个开源项目提交给 Apache 基金会,Apache Thrift 官网地址http://thrift.apache.org/

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

4、Thrift 主要由 5 部分组成:

1)语言系统以及 IDL 编译器:负责由用户给定的 IDL 文件生成相应语言的接口代码;

2)TProtocol:RPC 的协议层,可以选择多种不同的对象序列化方式,如 JSON 和 Binaru;

3)TTransport:RPC 的传输层,同样可以选择不同的传输层实现,如 Socket、NIO、MemoryBuffer 等;

4)TProcessor:作为协议层和用户提供的服务实现之间的纽带,负责调用服务实现的接口;

5)TServer:聚合 TProtocol、TTransport、TProcessor 等对象。

5、对于编解码框架,与之对应的就是 TProtocol 。由于 Thrift 的 RPC 服务调用和编解码框架绑定在一起,所以通常使用 Thrift 的时候会采取  RPC 框架的方式,但是它的 TProtocol 编解码框架还是可以以类库的方式独立使用的

6、Thrift 通过 IDL 描述接口和数据结构定义,它支持Java 8 种基本类型、Map、List、Set,支持可选和必选定义,功能非常强大。因此可以定义数据结构中的字段的顺序,可以支持协议的前向兼容。

7、Thrift 支持三种比较典型的编解码方式:

1)通用的二进制编解码

2)压缩的二进制编解码

3)优化的可选字段压缩编解码

8、由于支持二进制压缩编解码,所以 Thrift 的编解码性能表现也相当优异,远远超过 Java 序列化和 RMI 等。

Jboos · Marshaling 编解码

1、JBoss Marshalling 是一个 Java 对象的序列化 API 包,修正了 JDK 自带的序列化包的很多问题,但又保持跟 java.io.Serializable 接口的兼容。同时增加了一些可调的参数和附加的特性,并且这些参数和特性可通过工厂类进行配置。

2、JBoss Marshalling 官网地址:http://jbossmarshalling.jboss.org/

3、Marshalling 在 GitHub 开源地址:https://github.com/jboss-remoting/jboss-marshalling

4、相比于传统的 Java 序列化机制,Marshalling 的优点如下:

1)可插拔的类解析器,提供更加便捷的类加载定制策略,通过一个接口即可实现定制;

2)可插拔的预定义类缓存表,可以减小序列化的字节数组的长度,提升常用类型的对象序列化性能;

3)无需再实现 java.io.Serializable 接口,即可实现 Java 序列化;

4)通过缓存技术提升对象的序列化性能。

MessagePack 编解码

It's like JSON.but fast and small.

MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.

它像 JSON,但是更快更小。
MessagePack 是一种高效的二进制序列化格式。它允许您在 JSON 等多种语言之间交换数据,但它更快速更小巧。小整数被编码为单个字节,典型的短字符串除了字符串本身之外只需要一个额外的字节。

MessagePack 官网地址:https://msgpack.org/

MessagePack GitHub 开源地址:https://github.com/msgpack/msgpack

MessagePack Java 模块 GitHub 开源地址:https://github.com/msgpack/msgpack-java

核心压缩方式可参看官方说明:https://github.com/msgpack/msgpack/blob/master/spec.md

MessagePack is supported by over 50 programming languages and environments.(MessagePack 支持主流的 50 多种编程语言)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚩尤后裔-汪茂雄

芝兰生于深林,不以无人而不芳。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值