最近做一个终端5.0平台,里面使用了一些序列化的协议,比如xml,json,protobuf;有些地方使用感觉蛮不错,有些地方使用有些不合适,并且发现很多开源都在广泛使用序列化协议,这已经是一个基本的必备技能,于是我就想总结一下,为以后架构设计选择做铺垫;
什么是有序列化协议呢?序列化协议是数据载体的标准定义,使装载的数据可以在不同平台使用不同语言与具体数据进行有效的无损转化,协议本身与平台和语言无关;常用序列化协议有xml、json、protobuf;虽然现在网上大量这样相关资料,我也推荐一下;xml学习——http://www.w3school.com.cn/xml/;json学习——http://baike.baidu.com/link?url=RPylyGvvLzAvxPqV64EpE33WMnvRpsvZv-aPEdKBnFAfeyLuSZ1P02PpRM-oa5b1SBT1FX2H2ut1ie8lyP-7d_、http://www.bejson.com/;protobuf学习——http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/、http://www.searchtb.com/2012/09/protocol-buffers.html;
为什么要使用序列化协议?因为现在的应用都是要使用不同语言跨平台跨网络进行通信,那么怎么样使得数据交互过程中无损有效的交互就是必须要考虑的因素,而序列化协议就是为了解决这个问题而生;
选择序列化协议的时候我们应该考虑哪些因素?虽然序列化协议各有优劣,但是总体而言主要考虑以下几点:
<1>可读性;比如xml、json可读性就不错,protobuf序列化的数据基本不可读;
<2>空间占用;比如protobuf序列化的空间占用是java 序列化的1/9;json格式是java序列化的1/2.6;xml相比于java序列化来说,空间占用上有点优势,但不明显;
<3>序列化以及反序列化的响应时间;比如protobuf一次操作在1us左右,比java序列化时间快一个数量级;json格式一次操作在5us左右,与java序列化时间差不多,稍快;xml格式一次操作在100us左右,比java序列化时间慢一个数量级;
<4>表达数据的复杂性;我认为xml比json和protobuf更加能表达复杂数据一些;因为xml还有属性的概念;
<5>语言支持;protobuf原生支持——java、python、c++;json和xml基本都支持,因为也比较简单;
<6>扩展性;我认为protobuf的版本前向扩展性比json和xml要好,因为有专门的required、optional进行版本前向兼容;
具体参数比较参照:http://blog.csdn.net/kongls08/article/details/8562280;
这些序列化协议开源引擎总结:
<1>protobuf——Google Protocol Buffer;下载路径http://code.google.com/p/protobuf/downloads/list
<2>json——c++语言使用jsoncpp;下载路径http://www.oschina.net/p/jsoncpp
java语言使用jackson;下载路径http://www.oschina.net/p/jackson
c语言使用jansson;下载路径http://www.oschina.net/p/jansson
(注意:janson有些接口使用产生的内存要用户去释放,否则会有内存泄露)
其余可以参照http://www.oschina.net/project/tag/228/json
<3>xml——c/c++语言使用TinyXml;下载路径http://www.oschina.net/p/tinyxml
java语言使用xml-utilities;下载路径http://www.oschina.net/p/xml-utilities
使用场景:
<1>protobuf——protobuf的优点是占用空间小,序列化反序列化快;缺点是可读性不行;而网络之间数据通信数据越少越好,响应速度越快越好;反而对这个可读性要求不高;所以我认为用于跨网络之间数据通信比较合适;
<2>json——json的优点是可读性比xml稍差比protobuf好,空间和速度比protobuf差,比xml好;而局域网和同机器不同系统之间通信对性能要求不是特别高,对可读性有一定要求,这样可以方便调试;所以我任务用于局域网和同机器不同系统之间通信比较合适,或者跨语言接口数据封装;
<3>xml——xml的优点是可读性不错,非常符合人类思维;但是效率不好;而存储的数据对可读性要求比较高,对效率不高,因为不会经常读写;所以我认为xml用于数据存储比较合适;
那系统内部模块之间通信是否需要使用序列化协议装载数据呢? 在我们的5.0终端的设计中,模块之间通信也是选择protobuf进行的通讯,系统内部数据都是通过protobuf定义的;带来的麻烦是数据结构的定义很麻烦,增加了数据转换的开销;带来的好处暂时没有发现,只是为了预防后续数据结构的扩展;我个人表示这个是不合理的;因为这个明显带来了麻烦,而预防的后续数据扩展在系统内部模块要求不高,通过合理设计数据结构就可以满足;但是我们也发现有些开源数据格式的组装也是使用序列化协议的,比如xmlrpc使用xml封装数据,并使用HTTP协议作为传送机制,实现远程调用;这是为什么呢?因为这个是基础组件,有可能跨语言、跨平台进行远程调用;
所以我们使用序列化协议的时候要考虑一下几点:
<1>是否有可能跨语言;
<2>是否有可能跨平台;
最后总结:不要任何地方都使用序列化协议装载数据,要根据情况选择合适的序列化协议;