【033】Dubbo3从0到1系列之dubbo协议支持的序列化方式
文章目录
- 七、Dubbo协议支持的序列化
- 7.1 hessian
- 7.1.1 介绍
- 7.1.2 使用方式
- 7.2 Fastjson2
- 7.2.1 介绍
- 7.2.2 使用方式
- 7.2.3 配置启用
- 7.3 Fastjson
- 7.4 Avro
- 7.5 FST
- 7.6 Gson
- 7.7 Kryo
- 7.8 MessagePack
- 7.9 协议升级
七、Dubbo协议支持的序列化
7.1 hessian
7.1.1 介绍
Hessian序列化是一种支持动态类型、跨语言、基于对象传输的网络协议,Java对象序列化的二进制流可以被其他语言(如,c++,python)。特性如下:
- 自描述序列化类型。不依赖外部描述文件或者接口定义,用一个字节表示常用的基础类型,极大缩短二进制流。
- 语言无关,支持脚本语言
- 协议简单,比Java原生序列化高效
- 相比hessian1,hessian2中增加了压缩编码,其序列化二进制流大小是Java序列化的50%,序列化耗时是Java序列化的30%,反序列化耗时是Java序列化的20%。
7.1.2 使用方式
在 Dubbo 框架中,当使用 dubbo 通信协议时,默认使用 Hessian2 作为序列化。
# application.yml (Spring Boot)
dubbo:protocol:serialization: hessian2
# dubbo.properties
dubbo.protocol.serialization=hessian2
# or
dubbo.consumer.serialization=hessian2
# or
dubbo.reference.com.demo.DemoService.serialization=hessian2
或者
<dubbo:protocol serialization="hessian2" />
<!-- or -->
<dubbo:consumer serialization="hessian2" />
<!-- or -->
<dubbo:reference interface="xxx" serialization="hessian2" />
7.2 Fastjson2
7.2.1 介绍
FASTJSON v2是FASTJSON项目的重要升级,目标是为下一个十年提供一个高性能的JSON库。通过同一套API,
- 支持
JSON/JSONB两种协议,JSONPath是一等公民。 - 支持全量解析和部分解析。
- 支持
Java服务端、客户端Android、大数据场景。 - 支持
Kotlinhttps://alibaba.github.io/fastjson2/kotlin_cn - 支持
JSON Schemahttps://alibaba.github.io/fastjson2/json_schema_cn - 支持
Android 8+ - 支持
Graal Native-Image - 支持
JSON Schemahttps://alibaba.github.io/fastjson2/json_schema_cn
7.2.2 使用方式
➡️ 引入依赖
<dependencies><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.23</version></dependency>
</dependencies>
注:Fastjson2 序列化仅 Dubbo > 3.1.0 版本支持。在 Dubbo > 3.2.0 中将替代 Hessian 作为默认序列化方式。
7.2.3 配置启用
# application.yml (Spring Boot)
dubbo:protocol:serialization: fastjson2
# dubbo.properties
dubbo.protocol.serialization=fastjson2
# or
dubbo.consumer.serialization=fastjson2
# or
dubbo.reference.com.demo.DemoService.serialization=fastjson2
或者
<dubbo:protocol serialization="fastjson2" />
<!-- or -->
<dubbo:consumer serialization="fastjson2" />
<!-- or -->
<dubbo:reference interface="xxx" serialization="fastjson2" />
7.3 Fastjson
Fastjson 是一个 Java 库,可用于将 Java 对象转换为其 JSON 表示形式。它还可用于将 JSON 字符串转换为等效的 Java 对象。 Fastjson 可以处理任意 Java 对象,包括您没有源代码的预先存在的对象。
添加依赖:
<dependencies><dependency><groupId>org.apache.dubbo.extensions</groupId><artifactId>dubbo-serialization-fastjson</artifactId><version>3.3.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency>
</dependencies>
配置启用:
# application.yml (Spring Boot)
dubbo:protocol:serialization: fastjson
7.4 Avro
Avro是一种远程过程调用和数据序列化框架,是在Apache的Hadoop项目之内开发的。它使用JSON来定义数据类型和通讯协议,使用压缩二进制格式来序列化数据。它主要用于Hadoop,它可以为持久化数据提供一种序列化格式,并为Hadoop节点间及从客户端程序到Hadoop服务的通讯提供一种电报格式。
📌 添加依赖
<dependencies><dependency><groupId>org.apache.dubbo.extensions</groupId><artifactId>dubbo-serialization-avro</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.apache.avro</groupId><artifactId>avro</artifactId><version>1.11.1</version></dependency>
</dependencies>
🔝 配置启用
# application.yml (Spring Boot)
dubbo:protocol:serialization: avro
或者
# dubbo.properties
dubbo.protocol.serialization=avro
# or
dubbo.consumer.serialization=avro
# or
dubbo.reference.com.demo.DemoService.serialization=avro
或者
<dubbo:protocol serialization="avro" />
<!-- or -->
<dubbo:consumer serialization="avro" />
<!-- or -->
<dubbo:reference interface="xxx" serialization="avro" />
7.5 FST
FST序列化全称是Fast Serialization,它是对Java序列化的替换实现。既然前文中提到Java序列化的两点严重不足,在FST中得到了较大的改善,FST的特征如下:
- 比JDK提供的序列化提升了10倍,体积也减少 3-4 倍多
- 支持堆外Maps,和堆外Maps的持久化
- 支持序列化为JSON
🔝 添加依赖
<dependencies><dependency><groupId>org.apache.dubbo.extensions</groupId><artifactId>dubbo-serialization-fst</artifactId><version>3.3.0</version></dependency><dependency><groupId>de.ruedigermoeller</groupId><artifactId>fst</artifactId><version>3.0.3</version></dependency>
</dependencies>
✅ 配置启用
# application.yml (Spring Boot)
dubbo:protocol:serialization: fst
7.6 Gson
Gson是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。
<dependencies><dependency><groupId>org.apache.dubbo.extensions</groupId><artifactId>dubbo-serialization-gson</artifactId><version>3.3.0</version></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.10.1</version></dependency>
</dependencies>
# application.yml (Spring Boot)
dubbo:protocol:serialization: gson
7.7 Kryo
Kryo是一种非常成熟的序列化实现,已经在Twitter、Groupon、Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用。
<dependencies><dependency><groupId>org.apache.dubbo.extensions</groupId><artifactId>dubbo-serialization-kryo</artifactId><version>1.0.1</version></dependency><dependency><groupId>com.esotericsoftware</groupId><artifactId>kryo</artifactId><version>5.4.0</version></dependency><dependency><groupId>de.javakaffee</groupId><artifactId>kryo-serializers</artifactId><version>0.45</version></dependency>
</dependencies>
# application.yml (Spring Boot)
dubbo:protocol:serialization: kryo
7.8 MessagePack
MessagePack是一种计算机数据交换格式。它是一种二进制形式,用于表示简单的数据结构,如数组和关联数组。MessagePack 旨在尽可能紧凑和简单。
<dependencies><dependency><groupId>org.apache.dubbo.extensions</groupId><artifactId>dubbo-serialization-msgpack</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.msgpack</groupId><artifactId>msgpack-core</artifactId><version>0.9.3</version></dependency><dependency><groupId>org.msgpack</groupId><artifactId>jackson-dataformat-msgpack</artifactId><version>0.9.3</version></dependency>
</dependencies>
# application.yml (Spring Boot)
dubbo:protocol:serialization: msgpack
7.9 协议升级
在 3.1.0 版本中,Dubbo 默认支持的序列化协议新增对 Fastjson2 的支持。部分用户可能会考虑在现有的系统中对序列化协议进行升级,但服务端和客户端版本的差异可能导致客户端并不支持服务端的序列化协议。
在 3.2.0 版本中, Dubbo 的服务端引入新的配置 prefer-serialization,该特性可以完美解决服务端序列化升级过程中可能带来的风险。
最佳实践
- 先需要推动服务端的序列化协议升级,同时在服务端的暴露配置中需要添加
prefer-serialization配置。
比如:升级前的序列化协议是 hessian2,升级之后的序列化协议是 Fastjson2 那么在服务端的暴露配置中就应该添加如下所示的配置。
dubbo.provider.prefer-serialization=fastjson2,hessian2
dubbo.provider.serialization=hessian2
- 其次,客户端需要升级至和服务端相同版本
实现原理
dubbo 客户端序列化协议是根据服务端的注册配置来选择的(即服务端的serialization配置)。在请求阶段 dubbo 会把客户端的序列化协议组装到请求头上,服务端在进行反序列化时会根据请求头来确定反序列化协议。所以,如果服务端和客户端的版本不一致就可能会出现客户端序列化不了的情况。
为了解决这个情况,3.2.0 在客户端序列化的时候会优先使用 prefer-serialization 配置的协议,如果不支持 prefer-serialization 相关的协议,才会使用 serialization 配置的协议。(可以把 serialization 理解为一个兜底的配置)
