系统间通信(一)——数据交换序列化格式

  我们都知道,人与人之间的交流需要建立在某种语言基础之上,没有语言,人类便无法交流。这时有人不同意了,他说电视剧里不是有读心术吗,不交流也能知道对方在想什么。对于这个问题我只能“呵呵”了,如果你也同意他说的,那请点击右上角的X关掉这个页面(有些系统好像是左上角),因为下面的内容只适合不在梦境中的人。有了语言也不能代表能顺利沟通,还得建立在相同的语法上,你可以想象一下一个只懂本国汉语的中国人和一个只懂本国英语的英国人之间沟通的情形。在计算机领域为了保证系统间通信数据能够被处理,其数据会被做成特定的格式,而且要确保目标系统能够明白这种格式。为了保证信息数据传递的高效性,我们一定会将数据做成某种参与者都理解的格式。就像中文有其特定的语法结构(例如主谓宾,定状补),我们在系统间交换的数据也必须要有特定的格式,目标系统才能识别传递过去的数据。

  为了便于下面内容的理解我们在这里约定,发送数据方叫上游系统,接受数据方叫下游系统。本文重点讲解以Java作为开发语言的相关内容。两个系统间通信一般会经历如下6个步骤的流程:

    1. 上游系统收集需要发送的数据;
    2. 上游系统将需要发送的数据序列化成两个系统约定好格式数据载体;
    3. 上游系统通过相关网络协议发送数据载体;
    4. 下游系统接收数据载体;
    5. 下游系统反序列化接收到的数据载体;
    6. 下游系统处理保证数据 。

  在以上步骤中,步骤1和6在不同的系统有不同的行为,所以我们无法定义出统一的行为。本文所讲的数据交换序列化格式仅仅包括步骤2到步骤4中的4个动作。步骤2和5的为序列化和反序列化,此处必须是采用两系统已约定好的数据格式来生成数据载体,以及从数据载体中解析出我们需要的数据。不同的数据载体决定步骤3和4中我们采用什么网络协议来发送和接收数据载体,以及是同步还是异步传输。如果数据载体为文件载体(包括字符和字节文件),则传输的网络协议需要采用文件传输相关的协议,比如FTP或SFTP,当然也可以用HTTP协议来传输文件,但需提前约定文件上传下载的位置;如果数据载体为消息载体,则需要支持消息列队的消息中间件。除了以上两种常见的载体,实际操作我们可能会遇到各色各样的载体和对应的传输协议。

  目前业界比较流行的数据交换格式有Json、XML、Google ProtocolBuffer和系统间自行约定的格式。也有一些不那么常用但非常优秀的格式,他们通常用于特定领域,比如YAML和TLV(三元组编码),我们会简单的介绍他们,但不会太深究其原理。下面详细地介绍一下这些常用的格式:

  • XML:
    可扩展标记语言,这个语言由W3C(万维网联盟)进行发布和维护。XML语言应用广泛,扩展丰富,而且它独立于开发语言和平台。为了方便Java开发人员更好的使用它,Java为我们提供了JAX-WS和JAXB两种规范,用于在两个系统间传输和自动序列化和反序列化数据到Domain类。

    • JAXB(Java Architecture for XML Binding)可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。

    • JAX-WS(Java API for XML Web Services)规范是一组XML web services的JAVA API,JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP,在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。JAX-WS的运行时实现会将这些API的调用转换成为对应的SOAP消息。

  • JSON:
    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它和XML的设计思路是一致的:和语言无关(流行的语言都支持JSON格式描述:Go、Python、C、C++、C#、JAVA、Erlang、JavaScript等等);但是和XML不同,JSON的设计目标就是为了进行通信。要描述同样的数据,JSON格式的容量会更小。在当下的应用中,很多系统用JSON来取代XML。在XML中我们可以用JAXB来来实现XML和Java类之间的映射,其实我们也可以用JAXB并借助Jackson来实现Json与Java类之间的映射。

  • Protocol Buffers(protobuf):
    Protocol Buffers是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。它不依赖于语言和平台并且可扩展性极强。现阶段官方支持C++、JAVA、Python等三种编程语言,但可以找到大量的几乎涵盖所有语言的第三方拓展包。通过它,你可以定义你的数据结构,并生成基于各种语言的代码。这些你定义的数据流可以轻松地在传递并不破坏你已有的程序。并且你也可以更新这些数据而现有的程序也不会受到任何的影响。在Java中,我们只需要维护一个以.proto为后缀的文件,文件中使用Protocol Buffers定义好的描述语言,并可通过Maven插件在编译期生成对应的java代码,我们只需在应用中调用生成的Java API将Java对象转化成protobuf流,也可用其从protobuf流中解析并生成对应的Java对象。

  • YAML:
    YAML是一种直观的能够被电脑识别的的数据数据序列化格式。换种说法,YAML是一种很简单的类似于XML的数据描述语言,语法比XML简单很多。换种说法,它是一种很简单的类似于XML的数据描述语言,语法比XML简单很多。

  • TLV(三元组编码):
    T(标记/类型域)L(长度/大小域)V(值/内容域),通常这种信息格式用于金融、军事领域。它通过字节的位运算来进行信息的序列化/反序列化(据说微信的信息格式也采用的是TLV,但实际情况我不清楚):

  • 自定义的格式
    如果不想采用已有的格式,我们完全可以自定义一种,然后在两个系统内使用。比如,您可以先定义一个实体类,然后以“|”号分割每个属性来生成一个字符串,并将这个字符串作为一行写入一个字符文件,文件生成后通过SFTP发送到与下游系统约定好的目录;下游系统定时的扫描约定目录,在获得文件后,读取并用相同的分隔符解析各个属性,生成对应的对象,并将得到的值注入到这个对象中。这样就完成了一个简单的自定义格式。当然,实际自定义时的情况远比这个复杂。

  在了解过常用的序列化格式后,如何选取又变成一个需要解决的问题。其实这是一个仁者见仁智者见智的问题,每个程序员对这些格式都有不同的认识和偏好。有人喜欢XML有较好的可读性,也有人喜欢JSON的性能,或者喜欢有像Google这样的大公司做后盾来维护的Protobuf,甚至有人就喜欢自定义的格式。每一种选择都有合适的理由,但有一点我们是必须遵循的,就是在你系统中需采用有且只有一种格式,这样可以降低维护成本和维护周期。下面我给出我个人从架构师角度出发在选取时需要参考的几个点:

  1. 基于以下几点,我选择开发社区最常用的前三种格式XML、Json、Protocol Buffers中的一种:
    • 降低开发人员的学习成本——社区已有大量学习资料和案例;
    • 降低开发和维护成本——成熟的格式引入的bug也是最少的,出现bug时,只需替换对应的包即可解决;
    • 运行性能最好——这三种格式已经历过千百万个项目锤炼,性能早已达到非常高的级别;
    • 有较好的拓展性——方便替换和进行二次开发。
  2. 对于以上三种格式没法适应的情况,我建议自己定义格式,并在Team内部推广。自定义格式也有以下优点:
    • 常用格式的漏洞不会影响到自定义格式。
    • 对应加密的数据载体,黑客破解的成本可能更高,这取决你自定义的格式是否够高级。
    • 可以轻松的加入常用格式未有的功能或操作。

 

转载于:https://www.cnblogs.com/zengzhf/p/7693083.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值