1、java序列化
1、java序列化的实现
java提供了对象输入(ObjectInputStream),输出流(ObjectOutputStream),可以将java对象作为可存储的字节数组写入文件,也可以传输到网络上。
2、java序列化的目的
- 网络传输
- 对象持久化
2、java序列化的缺点
1、java了序列化从JDK1.1版本就已经提供,它不需要提供额外的类库,只需要实现java.io.Serializable,并生成序列ID即可,因此,它在诞生之初就得到了广发的应用
2、远程服务调用RPC时,很少直接使用java序列化进行消息的编解码和传输。
- 无法跨语言(java序列化属于java语言内部的私有协议,其他语言不支持,对于java序列化后的字节数组,别的语言无法进行反序列化)
- 序列化后的码流太大
- 序列化的性能太低
3、如何评判一个编解码框架的优劣,需要考虑的因素
- 是否支持跨语言,支持的语言种类是否丰富
- 编码后的码流大小
- 编解码的性能
- 类库是否小巧,api使用是否方便
- 使用者需要手工开发的工作量和难度
二、业界主流的编解码框架
| 名称 | 特点 | 备注 |
| Google的ProtoBuf |
将数据结构以.proto文件进行描述,通过代码生成工具可以生成对应数据结构的POJO对象和Protobuf相关的方法和属性 1、结构化数据存储格式(XML,JSON) 2、高效的编解码性能 3、语言无关,平台无关,扩展性好 4、官方支持java,c++,python三种语言 |
xml可读性和可扩展性好,但为了可读性而牺牲的空间开销非常大 protobuf 利用二进制编码,在空间额性能上具有更大优势 |
| facebook的thrift |
1、通用的二进制编解码 2、压缩二进制编解码 3、优化的可选字段压缩编解码 |
|
| JBoss Marshalling |
相比传统的java序列化机制,它的优点如下 1、可插拔的类解析器,提供更加便捷的类加载定制策略,通过一个接口即可实现定制 2、可插拔的对象替换技术,不需要通过集成方式 3、可插拔的预定义类缓存表,可以减小序列化的字节数组长度,提升常用类型的对象序列化性能 4、无需实现java.io.Serializable接口,即可实现java序列化 5、通过缓存技术提升对象的序列化性能 |
jboss内部使用,应用范围有限 |
| MessagePack |
高效的二进制序列化框架 1、粘包/半包支持 2、编解码高效,性能高 3、序列化之后的码流小 4、支持跨语言(java,python,ruby,haskell,c#,OCaml,Lua,Go,C,C++) |
三、MessagePack实现编解码技术
1、引入MessagePack的jar
<!--messagePack--> <dependency> <groupId>org.msgpack</groupId> <artifactId>msgpack</artifactId> <version>0.6.12</version> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.22.0-GA</version> </dependency>