3.1 升级至 3.2
Dubbo 3.2 升级与兼容性指南
对于绝大多数的用户,升级到 Dubbo 3.2.0 是完全平滑的,仅需要修改依赖包版本即可。
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.2.0</version>
</dependency>
或者
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
兼容性 CheckList
1. 序列化检查模式(重要!!!)
在 Dubbo 3.2.0 版本中,Dubbo 将默认开启序列化白名单的强校验,以提升 Dubbo 的安全性,避免远程命令执行的问题。 对于一些使用了泛型等可能存在扫描不全或者是服务规模较大的用户,我们建议您添加 -Ddubbo.application.serialize-check-status=WARN
配置。 观察一段时间后(通过日志、QoS 命令),如果没有触发安全告警,则可以配置强校验模式。
关于自定义白名单的配置,可以参考官网的 文档 / SDK 手册 / Java SDK / 高级特性和用法 / 提升安全性 / 类检查机制 一文进行配置。
Q1:为什么要开启序列化白名单的强校验?
由于 Java 本身机制的问题,Dubbo 支持的非 IDL 序列化天然允许访问任意类,这将可能导致远程命令执行(RCE)风险。
Q2:升级到 3.2 的最佳实践是什么?
我们建议所有用户在升级 Dubbo 3.2.0 版本前添加 -Ddubbo.application.serialize-check-status=WARN
配置以保证最佳的兼容性。否则可能导致线上数据异常的情况!
2. 默认序列化切换
Dubbo 3.2.0 版本开始默认序列化方式从 hessian2
切换为 fastjson2
,对于升级到 3.2.0 的应用,Dubbo 会自动尝试采用 fastjson2
进行序列化。
Q1:会不会影响和低版本的 Dubbo 互通?
不会。与低版本互通仍使用 hessian-lite
。原理可参考序列化协议升级指南一文。
Q2:为什么要切换默认序列化方式?
fastjson2
是一款高性能的序列化框架,性能优于 hessian2
,原生支持 JDK17、Native 等,以及完全向前兼容 hessian2
所有功能。 由于 hessian-lite
在未来维护难度越来越大,我们决定将默认序列化方式从 hessian2
切换为 fastjson2
。
Q3:和原生的 JSON 是什么关系?
Dubbo 中使用 fastjson2
的 JSONB 格式,而不是原生的 JSON 格式。JSONB 格式和JSON格式对应,能完全表示JSON,是一种二进制格式。 具体协议格式可以参考:JSONB 格式
Q4:如果我不想使用 fastjson2
,怎么办?
如果你不想使用 fastjson2
,可以配置 prefer-serialization
为 hessian2
覆盖默认配置。(如 dubbo.provider.prefer-serialization=fastjson2,hessian2
) 如果没有特殊的需求,我们不建议仍继续使用 hessian2
。
3. 默认关闭推空保护
Dubbo 3.2.0 版本开始默认关闭推空保护,即使注册中心推送空地址,Dubbo 也将不会保留最后一批 provider 信息。 如果需要开启推空保护,可以配置 dubbo.application.enable-empty-protection
为 true
。
Q1:关闭推空保护对我有什么影响?
在绝大部分场景下没有影响。 推空保护的目的是在注册中心出现故障并且主动推送空地址的时候,Dubbo 保留最后一批 provider 信息,以保证服务可用。 但是在大多数注册中心出现故障的时候,注册中心也不会推送空地址,只有一些特殊情况才会出现。 但如果开启推空保护,将对 Dubbo 的 Fallback 逻辑、心跳逻辑等造成较大的影响,给开发使用 Dubbo 带来困扰。
Q2:我想开启推空保护,怎么办?
如果在生产上为了高可用,需要开启推空保护,可以配置 dubbo.application.enable-empty-protection
为 true
。 目前已知开启推空保护会导致服务端应用从 2.6.x
、2.7.x
等仅支持接口级服务发现的版本升级到 3.x
之后回滚到原来版本出现异常,极端场景下会导致服务调用失败。 此外,开启推空保护后在服务端地址真的为空的时候出现较多的心跳异常、日志异常等。
4. 传递依赖变更
- Dubbo 3.2.0 版本开始默认不再在
dubbo-all
中 shadehessian-lite
的代码,而是使用传递依赖传递。如果你的应用中不需要使用hessian-lite
,可以将hessian-lite
从依赖中移除。 - Dubbo 3.2.0 版本开始在
dubbo-all
中不再传递gson
、fastjson
依赖,如果你的应用中需要使用gson
、fastjson
,请手动将gson
、fastjson
依赖添加到应用中。 - Dubbo 3.2.0 版本在
dubbo-all
中传递fastjson2
依赖。
5. 默认内部序列化工具切换
Dubbo 3.2.0 版本开始默认内部序列化工具从 fastjson
切换为 fastjson2
。
Q1:会不会影响 RPC 请求流量?
不会。内部序列化工具为 Dubbo 内部解析参数时使用,非 RPC 传输序列化协议。
Q2:为什么要切换默认内部序列化工具?
Dubbo 3.2.0 版本开始默认传递依赖不再传递 fastjson
和 gson
。出于兼容性考虑,默认内部序列化工具切换为 fastjson2
。
Q3:如果我的环境中没有 fastjson2
,怎么办?
Dubbo 支持多种序列化框架自动切换,如果你的环境中没有 fastjson2
,Dubbo 会自动尝试切换到 fastsjon
或 gson
。
Q4:我想指定 Dubbo 内部序列化工具,怎么办?
可以配置 dubbo.json-framework.prefer
参数,如 -Ddubbo.json-framework.prefer=gson
。
6. Triple 协议支持传递自定义异常
Dubbo 3.2.0 版本开始 Triple 协议支持回传自定义异常,而不是只能回传 RpcException
。如果服务接口会抛出异常的,在 Dubbo 3.2.0 版本以后将默认按照 Dubbo 协议一样回传自定义异常对象。
7. Triple 协议版本号对齐
Dubbo 3.2.0 版本开始,Triple 协议的通信要求客户端和服务端的版本号和分组一致,否则会找不到服务。与原生 gRPC SDK 互通时,Dubbo 侧不能配置分组和版本号。
Q1:Dubbo 3.2.0 以前是怎么样的?
1)Triple 会认为空版本号和 1.0.0 版本号一致,如果您的服务端和客户端版本号不一致,但是都是空版本号或者都是 1.0.0 版本号,是可以正常通信的。 2)对于没有匹配到版本号的服务,Triple 会尝试匹配任意版本号的服务,如果匹配到任意版本号的服务,也是可以正常通信的。
Q2:如何保证和原来行为是对齐的?
通过配置 -Ddubbo.rpc.tri.ignore-1.0.0-version=true -Ddubbo.rpc.tri.resolve-fallback-to-default=true
可以实现和 Dubbo 3.2.0 以前的行为。
最后修改 September 13, 2024: Refactor website structure (#2860) (1a4b998f54b)