前言
所谓的序列化解决方案,就是对象和二进制互相转换的解决方案。
为什么要采用二进制呢?这里有几个点要理解清楚。
1.应用程序里的数据是对象
2.网络传输的过程中一直是二进制
不管有没有进行对象和二进制互相转换,最终网络传输的都是二进制数据。
3.那为什么还要说进行对象和二进制的转换?
其实,这里的本质不在于转换,而在于双方的通信协议(也就是数据报文格式),必须采用二进制的数据报文协议才能够最大限度的减少数据报文的大小。
所以,总结如下,序列化解决方案,就是采用二进制通信协议(数据报文格式)。
不同序列化解决方案对比
json和google区别?
有 Protocol buffer 这种轻便的序列化反序列化工具,Json 为什么还会大量使用?
当然json的格式清晰,但是数据量显然大于protocol buffer
绝大多数情况下,JSON不是瓶颈,不需要替换或者优化。
中小公司切忌照抄Google的方案。
protobuf在文本为主的传输上并不会有很大的空间效率优化,带来的确是debug效率的下降。
跨语言的序列化方案
事实上的跨语言序列化方案只有三个: protobuf, thrift, json。
json体积太大,并且缺少类型信息,实际上只用在RESTful接口上,并没有看到RPC框架会默认选json做序列化的。 国内一些大公司的使用情况:
protobuf ,腾迅,百度等
thrift,小米,美团等
hessian, 阿里用的是自己维护的版本,有js/cpp的实现,因为阿里主用java,更多是历史原因。
序列化里的类型信息
序列化就是把对象转换为二进制数据,反序列化就把二进制数据转换为对象。
各种序列化库层出不穷,其中有一个重要的区别:类型信息存放在哪?
可以分为三种:
1、不保存类型信息
典型的是各种json序列化库,优点是灵活,缺点是使用的双方都要知道类型是什么。当然有一些json库会提供一些扩展,偷偷把类型信息插入到json里。
2、类型信息保存到序列化结果里
比如java自带的序列化,hessian等。缺点是类型信息冗余。比如RPC里每一个request都要带上类型。因此有一种常见的RPC优化手段就是两端协商之后,后续的请求不需要再带上类型信息。
3、在生成代码里带上类型信息
通常是在IDL文件里写好package和类名,生成的代码直接就有了类型信息。比如protobuf, thrift。缺点是需要生成代码,双方都要知道IDL文件。
类型信息看起来是一个小事,但在安全上却会出大问题,后面会讨论。
参考