APP为什么用JSON协议与服务端交互:序列化相关知识

      最后更新:2022-07-29 05:52:09 手机定位技术交流文章

      在设计或重构系统的过程中,特别是在设计分布式、大数据量系统里面,序列化选型是一个重要环节,因为序列化协议影响系统的通用性、健壮性、安全性,是否易于调试、是否便于扩展。

      理论和实践的序列部分,理论部分描述了序列是什么和该做什么.不感兴趣于实现(因为没有考虑具体实现,因此,我们当然不考虑优缺点并应用场景;实际部分描述了如何完成序列操作,物体如何表达自己,也就是说,从理论世界带进现实世界。序列理论部分与设计相等,实践部分与实现相等.

      理论

      序列理论的三个方面

      1. 序列化定义;

      2. 通信协议中的序列化状况;

      3. 序列化组件

      1.序列问题如何产生(序列的定义)

      互联网的发展导致了机器间通信的需要,机器之间的通信需要通信协议.通信协议还考虑如何显示和传输数据。序列是通信协议的一部分,它涉及数据的表示。OSI七层协议模型中的展现层(Presentation Layer)的主要功能是把对象转换成一段连续的二进制串,或者将二进制字符串转换为对象,即序列和逆序列。

      因此,序列和反序列的定义是:

      • 序列:将数据结构或对象转换为二进制字符串

      • 逆序列:将在序列过程中生成的二进制字符串转换为数据结构或对象

      注:只要可以传输到通信的另一端,例如uTF-8字符串,转换为二进制不一定需要。

      2.通信协议中的顺序定位

      1. OSI七层协议模型,序列化位于展示层(Presentation Layer)

      2. 在TCP/IP协议中,序列位于应用程序层。

      3.序列和反序列组件

      完整的序列协议包括以下组件:

      1. IDL(Interface description language)。参与通讯的各方需要对通讯的内容做相关约定。由于与语言和平台无关的原因,该公约需要使用与编程语言或平台无关的语言来描述。该语言被称为接口描述语言(IDL)。一个由IDL编写的协议叫做IDL文件。

      2. IDL Compiler:IDL文件中的约定需要一个编译器,将IDL文件转换成各编程语言的动态库。

      3. Stub/Skeleton Lib:序列和逆序列的代码。Stub是一个向客户部署的代码,一方面,它接收到应用程序层的参数,然后通过下层协议堆栈发送到服务端,然后在序列化后接收到服务端的结果数据,在向应用程序层逆序后,将骨架部署到服务端,它的功能与托管相反,从传输层接收序列参数,在向服务端应用程序层逆序后,应用层的实现结果被序列化,最后传递给客户端。

      序列组件之间的相互作用:

      序列组件之间的相互作用

      序列组件的概念与数据库的概念相似:

      实践

      序列化协议的考虑点

      1. 哪些编程语言支持和可以翻译

      2. 支持哪些平台,不论是跨平台(例如支持哪些硬件架构、操作系统)

      3. 流行度(序列涉及通信的两个方面,冷门序列协议需要高学习成本)

      4. 健壮性/鲁棒性

      5. 成熟度(协议须进行广泛、全面测试、实时系统测试、长期稳定运行)

      6. 是否简单易用

      7. 调试难度、可读性(数据序列和逆序列的准确性和业务准确性调试通常需要很长时间,良好的调试机制大大提高了开发效率.序列之后的二次序列往往不能被人眼读取.为了验证序列结果的正确性,作者必须同时写反序列程序。或者提供查询平台——这更昂贵;另一方面,如果读取器未能成功实现逆序列,很难确定它是否由反序列程序本身的错误引起,或者由编写部门编写错误的序列数据。如果数据在序列化后可读于人眼,这将大大提高调试效率,例如,XML和JSON具有人眼可读的优点。)

      8. 空间性能(Verbosity),即序列化以后的数据所占用的空间大小。

      9. 时间性能(Complexity)。复杂的序列化协议会导致较长的解析时间,这可能使得序列化和反序列化成为系统瓶颈。

      10. 扩展/兼容性:增加新领域是容易的吗? 业务系统需要快速更新,新的需要不断出现。 如果序列化协议具有良好的可扩展性,并支持自动增加新业务领域而不影响旧服务,这将提供巨大的系统灵活性。

      11. 例如,阿里的 fastjson经常有安全问题。

      12. 文档。

      已知的序列化协议

      早期的互联网序列化协议包括COM和CORBA。

      COM主要用于Windows平台,没有实现跨平台。COM序列化利用了编译器中的虚表,使得学习成本很高。序列化得到的数据与编译器紧耦合,扩展属性非常麻烦。

      CORBA更适合实现跨平台,跨语言。COBRA的主要问题是太多的参与者,导致版本过多,版本之间兼容性差,使用复杂晦涩。早期的设计成熟问题导致了COBRA的消失。J2SE 1.3的后续版本提供了基于CORBA协议的RMI-IIOP技术,CORBA可以使用纯Java开发。

      目前更流行的序列协议是XML、JSON、Protobuf、Hessian、Thrift和Avro。如果你想更多地了解序列化协议,参考文献: https://en.Wikipedia.Comparison_of_data-serialization_formats

      XML序列化协议

      XML是一种语言,一种描述性的语言,最初的目标是编码文件,它还需要可读和可读的编码数据。XML在设计时考虑到可读性,它还有跨机器、跨语言(这里指的是人类语言)等优点。XML历史悠久,1.Version 0早在1998年就成为标准。并被广泛使用至今,所以XML已经足够成熟了。因为XML可以编码具有复杂的结构的文件,因此XML也可以用于序列对象,所以设置XML列为序列协议(例如NET框架和gSOAP框架使用XML序列。但是当XML被用作序列协议时,它就显得冗长复杂。

      XML是自我描述的,XML本身是一个IDL。在XML中,有两种类型的IDL(即XML描述格式):DTD(Document Type Definition)和XSD(XML Schema Definition)。在一些编程语言中,XML有一个非常简单易用的序列API,不需要IDL文件或第三方IDL编译器(例如Java XStream)。XML在各种配置文件中广泛使用,例如O/R mapping、 Spring Bean Configuration File 等。

      优点:跨平台,跨语言,成熟,可读

      缺点:复杂冗余(空间复杂性)

      SOAP序列化协议

      SOAP(Simple Object Access protocol)是一个广泛使用的协议。基于XML的结构消息传输协议,XML用于序列和逆序列。SOAP支持多个传输协议,但最常用的是HTTP。SOAP协议IDL是WSDL(Web Service Description Language)。

      如果Java应用程序层对象是:

      用WSDL描述上述对象:

      SOAP是安全、可扩展、多语言、多平台的,支持多种传输协议。有广泛的群众基础,基于HTTP的传输协议使得SOAP在跨越防火墙时安全。XML的人眼可读性使它具有独一无二的可调性,互联网宽带的发展逐渐弥补了其空间开支方面的巨大不足。相对较低的资料或实时数据传输要求(例如第二级);SOAP是一个很好的选择。

      XML空间开销大,大的数据量和持久的应用程序场景不适合XML。XML序列和逆序列的空间和时间成本很大,对于达到MS级的性能要求的服务,不推荐XML。虽然WSDL具有描述对象的能力,但使用SOAP并不容易。对已习惯面向对象编程的用户来说,WSDL文件不是直观的。

      JSON序列化协议

      权威网站: http://json.com/

      JSON起源于JavaScript中的”Associative array”的概念,本质就是采用”Attribute-value”方式描述对象。事实上,在JavaScript和PHP等弱型语言中,类的描述方式就是Associative array。JSON有以下优点,它很快成为最广泛使用的序列化协议之一:

      1、这种Associative array格式匹配工程师对对象的理解。

      2、它也有XML的人眼可读(Human-readable)优点。

      3.序列化后的数据简化。

      JavaScript是预定支持,在Web浏览器应用场景中被广泛使用,是Ajax的事实标准协议。

      与XML相比,协议简单,分析速度快。

      6、松散的Associative array使得其具有良好的可扩展性和兼容性。

      因为json其实是associative array,对弱型编程语言中的概念类进行相应的处理,因此,JSON序列不需要IDL。原因:IDL的目的是写一个IDL文件,IDL文件在IDL编译器编译后生成一些代码(Stub/Skeleton)。这些代码真正负责相应的序列和反序列工作。 但是由于Associative array和一般语言里面的class太相似,他们之间存在着相应的关系。这允许我们使用一套标准代码进行相应的转换。对于自身支持Associative array的弱类型语言,语言本身具有在JSON序列之后操作数据的能力;对于Java,这种强有力的语言,可以用反射解决。

      JSON可以在许多应用场景中替换XML,使分析更加简单和快速。 典型的应用场景包括:

      1. 企业间传输的数据量相对较小,而实时服务需求相对较低(例如秒)。

      2. 基于Web浏览器的Ajax请求。

      3. 由于JSON具有非常强的后继兼容性,它适用于:经常变化的接口,需要高模块化的情况,例如移动应用程序与服务端之间的通信(为什么移动应用程序使用JSON协议与服务端相互作用)。

      4. JSON的典型应用场景是JSON+HTTP,适用于跨防火墙访问。

      总体看,JSON序列额外空间成本也较大(但比XML更小),不适合大型数据量或需要持久的场景。缺乏统一的IDL减少了参与者的限制,实际操作中往往只能采用文档方式来进行约定,这可能对调试造成一些不便,延长开发周期。因为在某些语言中,JSON序列和反序列需要反射机制,因此,不建议使用需要MS级性能的系统。

      Thrift序列化协议

      Thrift是Facebook开发的一个RPC框架,满足了大数据量、分布式、跨语言、跨平台数据通讯的需求。Thrift内部有一个自定义的序列化协议,即Thrift序列化协议。

      优点:与JSON和XML相比,Thrift提高了空间成本和分析性能,并适用于高性能系统;它支持多种编程语言,具有丰富的数据类型,并具有较强的兼容性与数据字段添加和删除。

      缺点:thrift序列在thrift框架内嵌入,然而,Thrift框架不提供外部访问的Thrift序列和逆序列,文档匮乏,用起来比较困难。Thrift序列后取得的数据是二进制阵列,不具有可读性,调试相对困难。储蓄序列和框架紧耦合,无法直接读取和写入持久层的数据,不适合数据持久性场景。

      Protobuf序列化协议

      权威网站: https://developers.google.protocol-buffers

      Protobuf具有串联协议的许多优点:

      1. 提供标准的IDL和IDL编译器, 对工程师非常友好.

      2. 序列数据是简单而紧凑的,并且序列后的数据量大约是XML的1/3到1/10。

      3. 分析速度非常快, 大约比XML快20-100倍.

      4. 它提供了一种友好的动态库,非常易于使用,并且只需要一个代码行来反演序列。

      5. Protobuf IDL文件对每个参与者业务造成了巨大的限制

      6. Protobuf与传输层无关,使用HTTP,具有良好的跨防火墙访问属性。

      Protobuf是一个纯展示层协议,可以用于多种传输层协议;Protobuf文档也非常完善。目前仅支持Java、C++、Python三种编程语言。另外Protobuf支持的数据类型较少,不支持常量。

      因此,Protobuf适用于具有高性能要求的跨公司RPC调用应用程序,而Protobuf同样适用于对象持久性。

      缺点: 语言支持不足, 没有标准的传输层协议绑定, 并且在各个公司中都比较难调试.

      Google gPRC框架采用了Protobuf序列协议作为参考。

      希斯序列协议

      Hessian(英语:Hessian)也是通用的序列协议,通常用于RPC框架,例如Dumbo和Pygeon,支持Hessian,并经常作为RPC框架的默认序列程序。

      Avro序列化协议

      Avro是Apache Hadoop的一个子项目,解决了JSON冗余问题,没有IDL问题.Avro提供两个序列格式:JSON和 Binary。在空间成本和分析性能方面,二进制格式与Protobuf相比较,JSON格式,方便调试.Avro支持多种数据类型,包含C++语言中的联盟类型。Avro支持JSON格式的IDL和与Thrift和Protobuf(实验阶段)类似的IDL,两者可以互换。 Schema可以同时传输数据,添加JSON自描述属性,这使得Avro非常适合动态类型语言。当Avro使文件持久时,通常与 Schema 存储,所以Avro序列文件本身具有自描述的特性,因此,它适用于Hive、Pig和MapReduce的持久数据格式。为不同版本的计划,打电话给RPC时,服务结束,客户在握手阶段可以确认对方的计划,增加数据分析速度。Avro分析性能高,数据序列简单,适用于高性能序列化服务。

      序列协议基准

      数据 https://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

      ​解析性能

      ​序列化之空间开销

      XML序列(Xstream)在性能和简单性上都差。

      與Protobuf相比,Thrift在空間時間支出方面有一些缺点。

      Protobuf 和 Avro 在 这 两 方面 都 非常 优越 。

      序列化协议的选型

      上述数种序列化协议具有各自的特点,适用于不同的场景:

      1.公司间的系统调用,性能要求100ms,基于XML的SOAP协议是值得考虑的方案。

      2、基于Web browser的Ajax,以及移动app与服务端之间的通讯,JSON是首选。对于性能要求不高或者以动态类型语言为主,传输数据小的场景,JSON是非常不错的选择。

      JSON或XML可以在更严格的调试环境下大大提高调试效率并降低开发成本。

      当场景的表演和简单度非常高时, 考虑Protobuf, Thrift, Avro.

      5.Protobuf和Avro是T级数据的持久应用场景的最佳选择。 如果数据在持久后存储在Hadoop子项目中,Avro是更好的选择。

      6.Avro的设计理念是面向动态类型语言的,而Avro是动态语言主要应用场景的最佳选择。

      7,一个持久层非Hadoop项目,具有静态类型语言基于场景,Protobuf更符合开发习惯。

      如果你需要提供一个完整的RPC解决方案, Thrift是一个很好的选择。

      9、如果序列化之后需要支持不同传输协议,或需要跨防火墙访问,Protobuf可以优先考虑。

      本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/30726.html

          热门文章

          文章分类