更新时间:2021-09-22 11:22:38 来源:极悦 浏览1091次
在Java开发工具当中,Java序列化工具是比较常用的,而且种类也有不少,下面小编就来做个对比:
Binary Formats & language-specific Ones
Javabuiltin (Java native), javamanual (根据成员变量类型手动编写), fstserliazation , kryo
二进制格式-通用语言-非特定 Ones
protobuf (Google) , Thrift (Facebook) , Avrogeneric, Hessian
JSON 格式
Jackson、Gson、Fastjson
Json-like:
CKS (Textual json-like format), BSON (json-like format with extended datatypes), Jacksonbson, MongoDB
基于 xml 的格式
Xmlxstream
Java序列化工具大致可以分为以上几类,简单概括分为二进制二进制和文本格式(JSON、XML)两大类。
在速度的比较上,一般有以下规律:
Binary > textual
Language-specific > Language-unspecific
在 textual 中,XML 冗余度低于 JSON,这使得它在文本序列化上更加 bson 和更加复杂JSON,框架选择更丰富、更优秀。下面重点介绍下Kryo、Fast-serialiation、Fastjson、Protocol-buffer
互联网公司使用Protobuf、Thrift、Avro等成熟的序列化解决方案来构建RPC框架是一个经过验证的解决方案。
(1)Java Native 序列化工具
Java本身提供的序列化工具基本上可以在大部分场景下对任务进行序列化,本文的序列化机制是非常详细的讲解(7820018),值得一读。Java自带的序列化工具在序列化过程中不仅需要记录对象的完整类名,还需要记录类的定义,包括所有其他引用的类,尤其是在非常大的开销下序列化单个对象时. 因为Java的序列化机制记录了所有的元数据,修改类的包名时反序列化是错误的。Java自序列化工具的性能问题总结如下:
单个对象的序列化是与所有成员变量(instsnce 变量)一起递归序列化,这是一种默认机制,很容易导致不必要的序列化开销。
序列化和反序列化的过程需要使用这种机制,使用反射机制递归合并所有成员变量的信息,如果没有定义自己的serialversionuid,那么对象和其他变量必须自己产生一个。上述过程成本很高。
使用默认的序列化机制,记录所有序列化类定义的完整信息,包括所有包名、父类信息和成员变量
(2)优化的Java序列化工具
Kryo
Kryo基于Java原生序列化机制的一些问题,做了很多优化,提供了很多序列化器,甚至封装了不安全序列化的类型,以及更多关于不安全序列化方法的类型,请注意这里, jdk1.7后默认关闭Unsafe Class(Sun.misc.Unsafe)包。更多 Kryo 参考 Kryo 维基介绍。
Fast-serialization
fst-serialozation是一个比较新的序列化工具,虽然从2-1的kryo的速度评价还有一些差距,但是根据我在现场的生产环境测试,kryo的效果几乎一致, 可以即时反序列化内容和渲染
(3)JSON
好的 JSON 解析工具还是比较好的,有些 JSON 解析工具甚至比一些二进制序列化方法还要快。
(4)协议缓冲区
Protocol buffers 是一种序列化结构化数据的技术,支持 C++、Java、Python 等多种语言,可用于持久化数据或序列化要通过网络传输的数据。与其他一些 XML 技术相比,这种技术的一个明显特点是它更节省空间(存储在二进制流中)、速度更快、更灵活。
另外,PROTOBUF 支持的数据类型比较少,不支持常量类型。由于其设计理念纯粹是表示层协议(Presentation layer),目前还没有专门支持PROTOBUF的RPC框架。
(5)节俭
Thrift 是 Facebook 开源的高性能、轻量级 RPC 服务框架,旨在满足当今大数据量、分布式、跨语言、跨平台数据通信的需求。然而,Thrift 不仅仅是一个序列化协议,而是一个 RPC 框架。与 JSON 和 XML 相比,thrift 在空间成本和解析性能上有很大的提升,对于性能要求很高的分布式系统来说是一个很好的 RPC 解决方案,但是因为 thrift 框架内嵌了 thrift 序列化,所以 thrift 框架本身并没有透露序列化和反序列化接口,这使得它很难与其他传输层协议(例如 HTTP)一起使用。
(6)阿夫罗
Avro解析性能高,序列化后的数据非常简洁,更适合高性能的序列化服务。
Avro 提供了两种序列化格式:JSON 格式或二进制格式。二进制格式在空间开销和解析性能上可以与protobuf相媲美,JSON 格式有助于测试阶段的调试。Avro 支持非常丰富的数据类型,包括 C++ 语言中的联合类型。AVRO支持JSON格式的IDL和类似于thrift和protobuf的IDL(实验阶段),可以相互转换。模式可以在传输数据的同时发送,加上 JSON 的自描述属性,这使得 Avro 非常适合动态类型语言。Avro通常在文件持久化时和schema一起存储,因此Avro序列化文件本身具有自描述属性,因此非常适合hive、pig和MapReduce的数据格式持久化。对于不同版本的schema,在进行RPC调用时,服务端和客户端可以在握手阶段相互确认schema,
Kryoregister、FST、Kryo、Gson、Fastjson、JDK
(1)JDK
public static byte[] serialize(Object obj) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); byte[] bs = baos.toByteArray(); baos.close(); oos.close(); return bs; } catch (IOException e) { throw new RuntimeException(e); }}public static Object deserialize(byte[] bits) { try { ByteArrayInputStream bais = new ByteArrayInputStream(bits); ObjectInputStream ois = new ObjectInputStream(bais); Object obj = ois.readObject(); bais.close(); ois.close(); return obj; } catch (Exception e) { throw new RuntimeException(e); }}
(2)Fastjson
JSON 库中涉及的最基本功能之一是序列化和反序列化。Fastjson 支持 Java bean 的直接序列化。使用 Com.alibaba.fastjson.JSON 类进行序列化和反序列化。
public static String serialize(Object obj){ String json = JSON.toJSONString(obj); return json;}public static Object deserialize(String json, Class<?> clazz){ Object obj = JSON.parseObject(json, clazz); return obj;}
(3)第一时间
FST Fast-serialization是一个重新实现的Java快速对象序列化开发包。序列化速度更快(2-10倍),体积更小,兼容JDK原生序列化。
Java Fast Serialization 库FST 2.0 版本已经发布,包名更改为不平滑升级。另外,出于稳定性考虑,官方建议使用最新的1.58版本。
static FSTConfiguration configuration = FSTConfiguration .createDefaultConfiguration();public static byte[] serialize(Object obj){ return configuration.asByteArray((Serializable)obj);}public static Object deserialize(byte[] sec){ return configuration.asObject(sec);}
(4)Gson
这以 JSON 格式使用,并使用 Google Gson 进行转义。
static Gson gson = new Gson();public static String serialize(Object obj){ String json = gson.toJson(obj); return json;}public static Object deserialize(String json, Class<?> clazz){ Object obj = gson.fromJson(json, clazz); return obj;}
对于原本采用Java Native序列化方案的系统,Kryo Fst-serializer是Java Native序列化方案的一个很好的替代方案,不仅体现了重新编程的简单性,而且在速度和性能上也有很大的提升,尤其是Fst -serializer,只是替换了Output/inputstream,升级的性能也很可观,工具刚出来,稳定性需要更多测试。
如果程序本身是JSON格式的序列化,可以考虑引入一个优秀的JSON解析库,General Service端Jackson就是一个流行的解析库。
Protobuffer 更多是消息交换格式的 XML 替代语言,尽可能快,但是编程需要定义消息格式,关于成员变量,业务复杂 javabean 成本比较复杂,对于稳定的现有系统,整体成本更高。
想了解更多Java技术,不妨关注极悦Java极悦在线学习,教程针对没有任何Java基础的读者学习,让你从入门到精通,主要介绍了一些Java基础的核心知识,让同学们更好更方便的学习和了解Java编程,感兴趣的同学可以关注一下。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习