序列化

在架构图中,在服务提供者和服务消费者两方面都有序列化层存在。
序列化就是把数据结构或者一些对象,转换为二进制串的过程,而反序列化是将在序列化过程中产生的二进制串转换成数据结构或者对象的过程。
image.png

支持不同的通信协议

dubbo协议

dubbo默认走dubbo协议,单一长连接,进行的是NIO异步通信,默认基于Hessian作为序列化协议。使用的场景是:传输数据量小(每次请求在100kb以内),但是并发量很高。

  1. 序列化(编码)是将对象序列化为二进制形式(字节数组),主要用于网络传输、数据持久化等;而反序列化(解码)则是将从网络、磁盘等读取的字节数组还原成原始对象,主要用于网络传输对象的解码,以便完成远程调用。
  2. 影响序列化性能的关键因素:序列化后的码流大小(网络带宽的占用)、序列化的性能(CPU资源占用);是否支持跨语言(异构系统的对接和开发语言切换)。
  3. Java默认提供的序列化:无法跨语言、序列化后的码流太大、序列化的性能差
  4. XML,优点:人机可读性好,可指定元素或特性的名称。缺点:序列化数据只包含数据本身以及类的结构,不包括类型标识和程序集信息;只能序列化公共属性和字段;不能序列化方法;文件庞大,文件格式复杂,传输占带宽。适用场景:当做配置文件存储数据,实时数据转换。
  5. JSON,是一种轻量级的数据交换格式,优点:兼容性高、数据格式比较简单,易于读写、序列化后数据较小,可扩展性好,兼容性好、与XML相比,其协议比较简单,解析速度比较快。缺点:数据的描述性比XML差、不适合性能要求为ms级别的情况、额外空间开销比较大。适用场景(可替代XML):跨防火墙访问、可调式性要求高、基于Web browserAjax请求、传输数据量相对小,实时性要求相对低(例如秒级别)的服务。
  6. Fastjson,采用一种“假定有序快速匹配”的算法。优点:接口简单易用、目前java语言中最快的json库。缺点:过于注重快,而偏离了“标准”及功能性、代码质量不高,文档不全。适用场景:协议交互、Web输出、Android客户端
  7. Thrift,不仅是序列化协议,还是一个RPC框架。优点:序列化后的体积小, 速度快、支持多种语言和丰富的数据类型、对于数据字段的增删具有较强的兼容性、支持二进制压缩编码。缺点:使用者较少、跨防火墙访问时,不安全、不具有可读性,调试代码时相对困难、不能与其他传输层协议共同使用(例如HTTP)、无法支持向持久层直接读写数据,即不适合做数据持久化序列化协议。适用场景:分布式系统的RPC解决方案
  8. AvroHadoop的一个子项目,解决了JSON的冗长和没有IDL的问题。优点:支持丰富的数据类型、简单的动态语言结合功能、具有自我描述属性、提高了数据解析速度、快速可压缩的二进制数据形式、可以实现远程过程调用RPC、支持跨编程语言实现。缺点:对于习惯于静态类型语言的用户不直观。适用场景:在Hadoop中做HivePigMapReduce的持久化数据格式。
  9. Protobuf,将数据结构以.proto文件进行描述,通过代码生成工具可以生成对应数据结构的POJO对象和Protobuf相关的方法和属性。优点:序列化后码流小,性能高、结构化数据存储格式(XML JSON等)、通过标识字段的顺序,可以实现协议的前向兼容、结构化的文档更容易管理和维护。缺点:需要依赖于工具生成代码、支持的语言相对较少,官方只支持Java C++ python。适用场景:对性能要求高的RPC调用、具有良好的跨防火墙的访问属性、适合应用层对象的持久化
  10. 其他:
  11. protostuff 基于protobuf协议,但不需要配置proto文件,直接导包即可
  12. Jboss marshaling 可以直接序列化java类, 无须实java.io.Serializable接口
  13. Message pack 一个高效的二进制序列化格式
  14. Hessian 采用二进制协议的轻量级remoting onhttp工具
  15. kryo 基于protobuf协议,只支持java语言,需要注册(Registration),然后序列化(Output),反序列化(Input

为了要支持高并发场景,一般是服务提供者就几台服务器,但是服务消费者有上百台服务器,每天调用量达到上亿次,此时使用长连接比较合适。
长连接和短连接的主要区别在于,建立连接过后,可以持续发送请求,无需再建立连接。
image.png
短连接,每次发送请求前,都先重新建立一次连接。
image.png

  • rmi协议

走Java二进制序列化,多个短连接,适合消费者和生产者数量不多的情况,适用于文件传输,一般较少使用。

  • hessian协议

适用于服务提供者比消费者数量还多的情况。

  • http 协议

走 json 序列化。

  • webservice

走 SOAP 文本序列化。

dubbo 支持的序列化协议

dubbo 支持 hession、Java 二进制序列化、json、SOAP 文本序列化多种序列化协议。但是 hessian 是其默认的序列化协议。

说一下 Hessian 的数据结构

Hessian 的对象序列化机制有 8 种原始类型:

  • 原始二进制数据
  • boolean
  • 64-bit date(64 位毫秒值的日期)
  • 64-bit double
  • 32-bit int
  • 64-bit long
  • null
  • UTF-8 编码的 string

另外还包括 3 种递归类型:

  • list for lists and arrays
  • map for maps and dictionaries
  • object for objects

还有一种特殊的类型:

  • ref:用来表示对共享对象的引用。

    为什么 ProtoBuf 的效率是最高的?

    可能有一些同学比较习惯于 JSON or XML 数据存储格式,对于 Protocol Buffer 还比较陌生。Protocol Buffer 其实是 Google 出品的一种轻量并且高效的结构化数据存储格式,性能比 JSON、XML 要高很多。
    其实 PB 之所以性能如此好,主要得益于两个:第一它使用 proto 编译器(静态编译,但时间比较慢),自动进行序列化和反序列化,速度非常快,应该比 XML 和 JSON 快上了 20~100 倍;第二,它的数据压缩效果好,就是说它序列化后的数据量体积小。因为体积小,传输起来带宽和速度上会有优化。