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


publicstatic <T> T decoder2(byte[
bytes)throws Exception {ByteArrayInputStream bis = new ByteArrayInputStream(bytes);Hessian2Input hessian2Input = new Hessian2Input(bis);Object obj = hessian2Input.readObject();return (T) obj;
通用性
Hessian与Protobuf、Thrift一样 , 支持跨语言RPC通信 。 Hessian相比其它跨语言PRC框架的一个主要优势在于 , 它不是采用IDL来定义数据和服务 , 而是通过自描述来完成服务的定义 。 目前Hessian已经实现了语言包括:Java、Flash/Flex、Python、C++、.Net/C#、D、Erlang、PHP、Ruby、Object-C 。
易用性
相较于Protobuf和Thrift , 由于Hessian不需要通过IDL来定义数据和服务 , 对于序列化的数据只需要实现Serializable接口即可 , 所以使用上相比Protobuf和Thrift更加容易 。
可扩展性
Hession序列化类虽然需要实现Serializable接口 , 但是它并不受serialVersionUID影响 , 能够轻松支持字段扩展 。
修改字段名称:反序列化后新字段名称为null或0(受类型影响) 。
新增字段:反序列化后新增字段为null或0(受类型影响) 。
删除字段:能够正常反序列化 。
修改字段类型:如果字段类型兼容能够正常反序列化 , 如果不兼容则直接抛出异常 。
性能
使用Hessian1.0协议序列化上面的测试用例 , 序列化结果大小为277 。 使用Hessian2.0序列化协议 , 序列化结果大小为178 。
序列化化与反序列化的时间开销如下:
可以看到Hessian1.0的无论在序列化后体积大小 , 还是在序列化、反序列化时间上都比Hessian2.0相差很远 。
数据类型和语法结构支持
由于Hession使用Java自描述序列化类 , 所以Java原生数据类型、集合类、自定义类、枚举等基本都能够支持(SynchronousQueue不支持) , Java语法结构也能够很好的支持 。
7Avro序列化框架
Avro是一个数据序列化框架 。 它是Apache Hadoop下的一个子项目 , 由Doug Cutting主导Hadoop过程中开发的数据序列化框架 。 Avro在设计之初就用于支持数据密集型应用 , 很适合远程或本地大规模数据交换和存储 。
使用Avro序列化分为三步:
(1)定义avsc文件:
{\"namespace\": \"com.yjz.serialization.avro\"\"type\": \"record\"\"name\": \"MessageInfo\"\"fields\": [{\"name\": \"username\"\"type\": \"string\"{\"name\": \"password\"\"type\": \"string\"{\"name\": \"age\"\"type\": \"int\"{\"name\": \"params\"\"type\": {\"type\": \"map\"\"values\": \"string\"

(2)使用avro-tools.jar编译生成Java代码(或maven编译生成):
java -jar avro-tools-1.8.2.jar compile schema src/main/resources/avro/Message.avsc ./src/main/java
(3)借助BinaryEncoder和BinaryDecoder进行编解码:
publicstaticbyte[
encoder(MessageInfo obj) throws Exception{DatumWriter<MessageInfo> datumWriter = new SpecificDatumWriter<>(MessageInfo.class);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();BinaryEncoder binaryEncoder = EncoderFactory.get().directBinaryEncoder(outputStreamnull);datumWriter.write(objbinaryEncoder);return outputStream.toByteArray();
publicstatic MessageInfo decoder(byte[
bytes) throws Exception{DatumReader<MessageInfo> datumReader = new SpecificDatumReader<>(MessageInfo.class);BinaryDecoder binaryDecoder = DecoderFactory.get().directBinaryDecoder(new ByteArrayInputStream(bytes)null);return datumReader.read(new MessageInfo()binaryDecoder);
通用性
Avro通过Schema定义数据结构 , 目前支持Java、C、C++、C#、Python、PHP和Ruby语言 , 所以在这些语言之间Avro具有很好的通用性 。
易用性
Avro对于动态语言无需生成代码 , 但对于Java这类静态语言 , 还是需要使用avro-tools.jar来编译生成Java代码 。 在Schema编写上 , 个人感觉相比Thrift、Protobuf更加复杂 。
可扩展性
给所有field定义default值 。 如果某field没有default值 , 以后将不能删除该field 。
如果要新增field , 必须定义default值 。
不能修改field type 。
不能修改field name , 不过可以通过增加alias解决 。
性能
使用Avro生成代码序列化之后的结果为:111 。 下面是使用Avro序列化的时间开销:
数据类型和语法结构支持
Avro需要使用Avro所支持的数据类型来编写Schema信息 , 所以能够支持的Java数据类型即为Avro所支持的数据类型 。 Avro支持数据类型有:基础类型(null、boolean、int、long、float、double、bytes、string) , 复杂数据类型(Record、Enum、Array、Map、Union、Fixed) 。
Avro自动生成代码 , 或者直接使用Schema , 不能支持在序列化类中定义java方法 。
三总结
1通用性
下面是从通用性上对比各个序列化框架 , 可以看出Protobuf在通用上是最佳的 , 能够支持多种主流变成语言 。