关于序列化的认识(一)

本篇主要就序列化的认识进行说明,不就某种序列化方式进行深入。

什么是序列化?

      序列化对于大部分开发人员是一个熟悉又遥远的词,我们经常要用到序列化,但是又不清楚为什么要序列化。我们以Java提供的序列化机制为例,它可以将对象的状态信息转变为二进制数据,实际上这个过程就是将内存中的数据转换为某种可持久化或者可传输的格式的过程。这也是序列化的过程,反之反序列化则是将数据重新读入内存的过程。

为什么需要序列化?

      这个问题也是大多数人最想知道的一个问题,同样我还是以Java为例,我们知道,Java程序的运行时依赖于JVM的,只有jvmJVM的时候,对象才可能存在(这里说的对象是内存中的对象,而非以某种形式持久化存在的),也就是说对象的生命周期是不会超过JVM生命周期的,但是我们往往需要希望能够在JVM停止运行后保存对象的状态,以便在别的地方使用。这也是序列化的第一个作用,将对象字节序列持久化。
      对于现在的大多数应用来说,都是网络应用,那么这就需要进行网络传输,我们知道,对象是存在于内存中的,显然是无法进行网络传输的,所以我们需要以一种方式来传输对象,这也是序列化的第二个作用。
总结:序列化实际上是为了让内存中的对象或者数据结构以一种可以存储和传输的格式存在。

序列化的方式

序列化的方式主要是两种,文本方式与二进制方式,如何进行选择也是很重要的一点,我主要考虑以下方面,

  • 通用性
    序列化机制在一定程度上要能够弥补OS之间的差异,方便进行传输,所以在选择序列化协议的时候,我们会考虑是否支持跨平台、跨语言。如果不支持,在技术层面上的通用性就大大降低了。例如Java本身提供的serialization机制无法在非JVM平台上使用,限制了它的通用性。如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。
  • 安全性 / 访问限制
    考虑到对外提供接口的兼容性,我们通常会采用REST+JSON的方案,用于内网通信的RPC通常使用二进制方式序列化,因为网络中只有字符串可以穿透防火墙,HTTP位于应用层,跨防火墙,可以在不同的局域网之间通信,而HTTP本身是一个文本协议,虽然可以传输二进制数据,但是通常需要经过BASE64或者MIME编码(HTTP2支持二进制流),所以会选择兼容性更好以及本身就是文本格式的JSON或者XML。对于RPC来说,RPC 使用TCP协议位于传输层,TCP是一种二进制协议,对二进制数据提供天然的支持,并且大多是用于内网通信,所以会选择效率更好的二进制序列化方式(关于传输协议:不同之处在于协议是围绕数据结构还是围绕文本字符串)。
    从安全性的角度考虑,二进制协议很方便进行加密,防止协议被破解,从而保护了传递的信息,增加协议破解的难度,而文本协议方便解读,并不适合进行加密。
  • 可扩展性/兼容性
    以JSON和XML为主的文本格式,如果需要增加一些条件,直接添加Key和Value就可以了,扩展方便,而二进制数据如果修改已有字段的顺序就会造成消息无法正确解析。

二进制序列化的数据因为是严格的内存到对象的转换,所以要求发送方与接收方的的机器字节序保持一致,否则无法正确解析。而文本格式的数据对于消息的发送方和接收方的采用的编程语言没有严格的限制,对于多语言编写提供了便利。

  • 性能
    空间开销(Verbosity), 序列化需要在原有的数据上加上描述字段,以为反序列化解析之用。二进制数据只保存了必须的信息,在需要传递大量信息的时候,对于磁盘和带宽的节省是非常明显的。而对于JSON和XML而言,因为存在大量描述性的信息,进行序列化的额外空间开销比较大,对于大数据量服务或持久化,这意味着巨大的内存和磁盘开销。

时间开销(Complexity),以Java为例,某些序列化方式需要依赖反射,往往会导致比较长时间的解析时间,这可能会成为应用的瓶颈。

  • 可读性
    序列化后的二进制数据往往不具备人眼可读性,为了验证序列化结果的正确性,写入方不得同时撰写反序列化程序,如果序列化后的数据人眼可读,这将大大提高调试效率, XML 和 JSON 就具有人眼可读的优点。

参考文献:
https://www.infoq.cn/article/serialization-and-deserialization
http://cn.voidcc.com/question/p-prmzkbxa-mb.html
https://www.liaoxuefeng.com/wiki/1016959663602400/1017624706151424
https://studygolang.com/articles/7855
https://hhbbz.github.io/2017/06/25/%E4%BB%8EDubbo%E6%B5%85%E8%B0%88RPC%E5%92%8CHTTP/

你可能感兴趣的:(关于序列化的认识(一))