什么是序列化反序列化
网络传输的数据必须是二进制数据,但调用方的出入参都是对象,所以需要把对象转化成可传输的二进制,并且要求算法是可逆的,这个过程叫做序列化。服务提供方可以从二进制数据中分割出不同的请求,根据请求类型和序列化类型,把二进制的数据逆向还原成请求对象,这个过程叫反序列化。
常用序列化
- JDK原生序列化
序列化过程就是在读取对象数据的时候,不断加入一些特殊的分隔符,这些特殊的分隔符用于在反序列化过程中截断用。 - JSON
JSON是典型的Key-Value方式,没有数据类型,是一种文本型序列化框架。
需要注意:JSON进行序列化额外空间开销比较大,需要巨大的内存和磁盘开销;
JSON没有类型,但像JAVA这种强类型语言需要反射统一解决,所以性能不会太好 - Hessian
Hessian是动态类型,二进制,紧凑的,并且可跨语言一只的一种序列化框架。比上述两种更紧凑序列化高效很多,所以生成的字节数也更小。
但是不能支持Linked系列,Locale类,Byte/Short反序列化会变成Integer - Protobuf
是Google公司内部的混合语言标准。轻便高效的结构化数据存储格式,用于结构化数据序列化。使用时需要定义IDL,(Interface description language),然后使用不同语言的IDL编译器,生成序列化工具类。
优点是:序列化后的提及比JSON,Hessian小很多。IDL能清晰的描述语义,能够保证应用程序之间的类型不会丢失,不需要类似的XML解析器
。序列化反序列化很快,不需要通过反射获取类型。消息格式升级和兼容性不错,可以做到向后兼容。
缺点不支持Map、list集合对象,需要包在对象里面
如何选择序列化
需要考虑下的因素,性能、效率以及性能开销。
序列化之后的二进制数据提及大小。序列化后的字节数据体积越小,网络传输的数据量越小,传输数据越快,传输速度直接关系到请求相应的耗时。
同时要考虑序列化的 安全性,通用性以及兼容性。
优先级高低
安全性>通用性>兼容性>性能>效率>空间开销
容易遇到的问题
对象过于复杂;
对象过于庞大。
对象有复杂的继承关系 。
总结
服务调用的稳定性和可靠性相对于性能和耗时更重要。对于RPC调用来说,最为耗时最耗性能的操作大多是服务提供者执行业务逻辑的操作,这是序列化的开销对于服务整体的开销相对影响比较小。
构造入参与返回值对象的注意点
- 对象要尽量简单,没有太多的依赖关系,属性不要太多,尽量高内聚。
- 入参对象与返回值兑现个体积不要太大,不要传太大的集合
- 尽量使用简单的蟾宫的开发语言原生的对象,尤其是集合类
- 对象不要有复杂的继承关系。