Java|几种Java常用序列化框架的选型与对比( 四 )


可以看出protobuf的反序列化性能要比FST、Kryo差一些 。
数据类型和语法结构支持
Protobuf使用IDL定义Schema所以不支持定义Java方法 , 下面序列化变量的测试:
注:List、Set、Queue通过protobuf repeated定义测试的 。 只要实现Iterable接口的类都可以使用repeated列表 。
5Thrift序列化框架
Thrift是由Facebook实现的一种高效的、支持多种语言的远程服务调用框架 , 即RPC(Remote Procedure Call) 。 后来Facebook将Thrift开源到Apache 。 可以看到Thrift是一个RPC框架 , 但是由于Thrift提供了多语言之间的RPC服务 , 所以很多时候被用于序列化中 。
使用Thrift实现序列化主要分为三步 , 创建thrift IDL文件、编译生成Java代码、使用TSerializer和TDeserializer进行序列化和反序列化 。
(1)使用Thrift IDL定义thrift文件:
namespace java com.yjz.serialization.thrift
structMessageInfo{1: string username;2: string password;3: i32 age;4: map<stringstring> params;
(2)使用thrift编译器生成Java代码:
thrift--genjavamessage.thrift
(3)使用TSerializer和TDeserializer进行编解码:
publicstaticbyte[
encoder(MessageInfo messageInfo) throws Exception{TSerializer serializer = new TSerializer();return serializer.serialize(messageInfo);publicstatic MessageInfo decoder(byte[
bytes)throws Exception{TDeserializer deserializer = new TDeserializer();MessageInfo messageInfo = new MessageInfo();deserializer.deserialize(messageInfobytes);return messageInfo;
通用性
Thrift和protobuf类似 , 都需要使用IDL定义描述文件 , 这是目前实现跨语言序列化/RPC的一种有效方式 。 Thrift目前支持 C++、Java、Python、PHP、Ruby、 Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk、OCaml、Delphi等语言 , 所以可以看到Thrift具有很强的通用性 。
易用性
Thrift在易用性上和protobuf类似 , 都需要经过三步:使用IDL编写thrift文件、编译生成Java代码和调用序列化与反序列化方法 。 protobuf在生成类中已经内置了序列化与反序列化方法 , 而Thrift需要单独调用内置序列化器来进行编解码 。
可扩展性
Thrift支持字段扩展 , 在扩展字段过程中需要注意以下问题:
修改字段名称:修改字段名称不影响序列化与反序列化 , 反序列化数据赋值到更新过的字段上 。 因为编解码过程利用的是编号对应 。
修改字段类型:修改字段类型 , 如果修改的字段为optional类型字段 , 则返回数据为null或0(数据类型默认值) 。 如果修改是required类型字段 , 则会直接抛出异常 , 提示字段没有找到 。
新增字段:如果新增字段是required类型 , 则需要为其设置默认值 , 负责在反序列化过程抛出异常 。 如果为optional类型字段 , 反序列化过程不会存在该字段(因为optional字段没有赋值的情况 , 不会参与序列化与反序列化) 。 如果为缺省类型 , 则反序列化值为null或0(和数据类型有关) 。
删除字段:无论required类型字段还是optional类型字段 , 都可以删除 , 不会影响反序列化 。
删除后的字段整数标签不要复用 , 负责会影响反序列化 。
性能
上面的测试用例 , 使用Thrift序列化后的字节大小为:257 , 下面是对应的序列化时间与反序列化时间开销:
Thrift在序列化和反序列化的时间开销总和上和protobuf差不多 , protobuf在序列化时间上更占优势 , 而Thrift在反序列化上有自己的优势 。
数据类型和语法结构支持
数据类型支持:由于Thrift使用IDL来定义序列化类 , 所以能够支持的数据类型就是Thrift数据类型 。 Thrift所能够支持的Java数据类型:
8中基础数据类型 , 没有short、char , 只能使用double和String代替 。
集合类型 , 支持List、Set、Map , 不支持Queue 。
自定义类类型(struct类型) 。
枚举类型 。
字节数组 。
Thrift同样不支持定义Java方法 。
6Hessian序列化框架
Hessian是caucho公司开发的轻量级RPC(Remote Procedure Call)框架 , 它使用HTTP协议传输 , 使用Hessian二进制序列化 。
Hessian由于其支持跨语言、高效的二进制序列化协议 , 被经常用于序列化框架使用 。 Hessian序列化协议分为Hessian1.0和Hessian2.0 , Hessian2.0协议对序列化过程进行了优化(优化内容待看) , 在性能上相较Hessian1.0有明显提升 。
使用Hessian序列化非常简单 , 只需要通过HessianInput和HessianOutput即可完成对象的序列化 , 下面是Hessian序列化的Demo:
publicstatic <T> byte[
encoder2(T obj) throws Exception{ByteArrayOutputStream bos = new ByteArrayOutputStream();Hessian2Output hessian2Output = new Hessian2Output(bos);hessian2Output.writeObject(obj);return bos.toByteArray();