3.2 升级至 3.3
Dubbo 3.3 升级与兼容性指南
对于绝大多数的用户,升级到 Dubbo 3.3.0 是完全平滑的,仅需要修改依赖包版本即可。
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.3.0</version>
</dependency>
或者
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
兼容性 CheckList
1. 默认序列化切换
Dubbo 3.3.0 版本开始默认序列化方式从 fastjson2
切换为 hessian2
,对于升级到 3.3.0 的应用,Dubbo 会自动尝试采用 hessian2
进行序列化。
Q1:为什么要切换默认序列化方式?
hessian2
为 Dubbo 3.1.x 及以下版本中默认的序列化,长期的生产验证了其稳定性和兼容性,在评估了向前兼容性和长期可维护性后,Dubbo 团队决定将 hessian-lite
升级到最新 hessian4
主干版本,以支持 JDK17 和 JDK21。
升级到 Dubbo 3.3.0 以后,依赖的 hessian-lite
版本将同步升级为 4.0.x
,主要包含以下修改:
- 同步 hessian 到上游 4.0.66 版本
- 修复 JDK17 及 JDK21 下类可见性带来的兼容性问题
- 支持 Record、ImmutableCollections 等 JDK9+ 特性
Q2:会不会影响和低版本的 Dubbo 互通?
部分场景下可能会有影响,具体如下:
- Dubbo 3.3.x Consumer 与 Dubbo 3.2.x Provider 互通时默认使用 Dubbo 3.2.x 中
fastjson2
优先的策略,无兼容性问题 - Dubbo 3.3.x Consumer 与 Dubbo 3.1.x 及以下版本 Provider 互通时默认使用 Dubbo 3.2.x 中
fastjson2
优先的策略,无兼容性问题 - Dubbo 3.2.x Consumer 与 Dubbo 3.3.x Provider 互通时默认使用 Dubbo 3.3.x 中
hessian2
优先的策略,此时由于 Dubbo 3.2.x Consumer 中携带的hessian2
为低版本的,在 JDK >= 17 的场景下可能会出现兼容性问题,建议按照 Q3 中的最佳实践进行升级。 - Dubbo 3.1.x 及以下版本 Consumer 与 Dubbo 3.3.x Provider 互通时默认使用 Dubbo 3.3.x 中
hessian2
优先的策略,此时由于 Dubbo 3.1.x 及以下版本 Consumer 中携带的hessian2
为低版本的,在 JDK >= 17 的场景下可能会出现兼容性问题,建议按照 Q3 中的最佳实践进行升级。
原理可参考序列化协议升级指南一文。
Q3:升级序列化最佳实践是什么?
- 从 Dubbo 3.2.x 升级到 3.3.x 时,建议配置
prefer-serialization
为fastjson2,hessian2
保持与 3.2.x 一致,待全集群升级完毕后在删除该配置,使用hessian2
序列化 - 从 Dubbo 3.1.x 及以下版本升级到 3.3.x 时,无需配置
prefer-serialization
,但需要注意避免与 JDK 升级一起进行,以免出现兼容性问题
Q4:如果我仍想使用 fastjson2
,怎么办?
如果你不想使用 hessian2
,可以配置 prefer-serialization
为 fastjson2
覆盖默认配置。(如 dubbo.provider.prefer-serialization=fastjson2,hessian2
)
2. 使用 register=false
不注册时将无法通过 QoS 手动注册
如果注册中心配置中配置了 dubbo.registry.register=false
或者指定服务配置 dubbo.provider.register=false
:
- 在 Dubbo 3.2.x 及以前版本中,默认 Dubbo 不自动注册,使用 QoS 命令(
curl http://127.0.0.1:22222/online
)可以实现注册 - 在 Dubbo 3.3.x 中,默认 Dubbo 不自动注册,使用 QoS 命令也无法注册
Q1: 为什么要做这个调整?
为了避免有的用户使用优雅上下线和隔离环境配置预期不一致,造成跨环境错误注册的情况,将 register=false
定义为永远不注册,delay=-1
且 -Ddubbo.application.manual-register=true
定义为延迟到手动注册。
Q2: 实现优雅上线的最佳实践是什么?
简单来说需要完成两个配置:delay=-1
且 -Ddubbo.application.manual-register=true
delay=-1
实现指定服务允许优雅上线:
- 如果需要对全部的服务都进行优雅上线,可以在
dubbo.provider.delay=-1
配置 - 如果只需要对部分服务进行优雅上线,可以在指定服务配置
delay=-1
-Ddubbo.application.manual-register=true
实现手动注册: 对于需要进行优雅上线的机器,配置 -Ddubbo.application.manual-register=true
JVM 参数
完善启动脚本: 对于需要进行优雅上线的机器,启动脚本中在启动结束后,主动调用 QoS 命令 curl http://127.0.0.1:22222/online
进行注册
考虑因素:
- 全局一套代码,无论是线上环境、测试环境均对需要优雅上线的服务进行配置
delay=-1
- 仅对线上环境进行
-Ddubbo.application.manual-register=true
配置,测试环境不配置,保证测试环境的服务能够自动注册
3. Nacos 兼容订阅默认关闭
从 Dubbo 3.3.x 版本开始,将不再订阅 Dubbo 2.7.3 及以前版本的兼容服务名,如果仍需要订阅,请配置 -Dnacos.subscribe.legacy-name=true
。
Q1: 为什么要做这个调整?
在 Dubbo 2.7.3 及以前版本中,Dubbo 服务注册到 Nacos 时,订阅格式为 providers(:{interfaceName})(:{version})(:{group})
,其中每个字段如果本身未空,会连带前面的 :
也一起省略,导致订阅名字不唯一,无法精确订阅。
如:
- 接口名:
com.foo.BarService
,版本:1.0.0
,分组:baz
,订阅名字为providers:com.foo.BarService:1.0.0:baz
- 接口名:
com.foo.BarService
,版本:空,分组:baz
,订阅名字为providers:com.foo.BarService:baz
- 接口名:
com.foo.BarService
,版本:baz
,分组:空,订阅名字为providers:com.foo.BarService:baz
如上,2 和 3 的订阅名字是一样的,但实际上是不同的服务。
为了解决这个问题,Dubbo 2.7.4 及以后版本中,订阅名字将会变为 providers:({interfaceName}):({group}):({version})
,保证订阅名字的唯一性。
如:
- 接口名:
com.foo.BarService
,版本:1.0.0
,分组:baz
,订阅名字为providers:com.foo.BarService:1.0.0:baz
- 接口名:
com.foo.BarService
,版本:空,分组:baz
,订阅名字为providers:com.foo.BarService::baz
- 接口名:
com.foo.BarService
,版本:baz
,分组:空,订阅名字为providers:com.foo.BarService:baz:
4. Dubbo Spring Boot Starters 更新
在 Dubbo 3.3.x 中,Dubbo Spring Boot Starters 为了方便依赖管理,提供了更多的 Starter 依赖。
此外:为了遵循 Spring 规范的命名规范,从 3.3.0 版本开始,可观测相关 Starter 的 artifactId 从 dubbo-spring-boot-observability-starter
更名为 dubbo-observability-spring-boot-starter
。
Q1: Dubbo 3.3.x 版本中的 Starter 有哪些?
以下是 Dubbo 官方社区提供的 starter 列表(3.3.0+ 版本),方便在 Spring Boot 应用中快速使用:
dubbo-spring-boot-starter
,管理 dubbo 核心依赖,用于识别 application.properties 或 application.yml 中dubbo.
开头的配置项,扫描 @DubboService 等注解。dubbo-spring-boot-starter3
,管理 dubbo 核心依赖,与 dubbo-spring-boot-starter 相同,支持 spring boot 3.2 版本。dubbo-nacos-spring-boot-starter
,管理 nacos-client 等依赖,使用 Nacos 作为注册中心、配置中心时引入。dubbo-zookeeper-spring-boot-starter
,管理 zookeeper、curator 等依赖,使用 Zookeeper 作为注册中心、配置中心时引入(Zookeeper server 3.4 及以下版本使用)。dubbo-zookeeper-curator5-spring-boot-starter
,管理 zookeeper、curator5 等依赖,使用 Zookeeper 作为注册中心、配置中心时引入。dubbo-sentinel-spring-boot-starter
,管理 sentinel 等依赖,使用 Sentinel 进行限流降级时引入。dubbo-seata-spring-boot-starter
,管理 seata 等依赖,使用 Seata 作为分布式事务解决方案时引入。dubbo-observability-spring-boot-starter
,加入该依赖将自动开启 Dubbo 内置的 metrics 采集,可用于后续的 Prometheus、Grafana 等监控系统。dubbo-tracing-brave-spring-boot-starter
,管理 brave/zipkin、micrometer 等相关相关依赖,使用 Brave/Zipkin 作为 Tracer,将 Trace 信息 export 到 Zipkin。dubbo-tracing-otel-otlp-spring-boot-starter
,管理 brave/zipkin、micrometer 等相关相关依赖,使用 OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 OTlp Collector。dubbo-tracing-otel-zipkin-spring-boot-starter
,管理 brave/zipkin、micrometer 等相关相关依赖,使用 OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 Zipkin。
5. 迁移 dubbo-compiler 和 dubbo-native-plugin 到 dubbo-maven-plugin
在 3.3 版本中,Dubbo 移除了 dubbo-native-plugin,同时 dubbo-native-plugin 相关的功能都将迁移至 dubbo-maven-plugin。此外,在 dubbo-maven-plugin 中也新增了对 dubbo-compiler 的支持。
更多过于 dubbo-maven-plugin 的说明请参考配置详情。
Q1:为什么要做这个迁移和调整?
- 为了提升用户的使用体验,后续dubbo有关maven的插件能力都将统一使用dubbo-maven-plugin来提供。方便Dubbo用户使用和接入。而不需要一个特性对应一个插件,导致用户需要依赖多个plugin。
- 更加有利于后续Dubbo提供maven plugin能力时的维护和特性增强。
Q2:如何迁移配置?
- 使用 Native Image 时,原配置为:
<plugin>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-maven-plugin</artifactId>
<version>${dubbo.version}</version>
<configuration>
<mainClass>com.example.nativedemo.NativeDemoApplication</mainClass>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>dubbo-process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
需要替换为:
<plugin>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-maven-plugin</artifactId>
<version>${dubbo.version}</version>
<configuration>
<mainClass>org.apache.dubbo.registry.consumer.NativeDemoConsumerRegistryApplication</mainClass>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>dubbo-process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
注:仅需要替换 artifactId
- 使用 Triple + Protobuf 时,原配置为:
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
<protocPlugins>
<protocPlugin>
<id>dubbo</id>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-compiler</artifactId>
<version>${dubbo.compiler.version}</version>
<mainClass>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator</mainClass>
</protocPlugin>
</protocPlugins>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
可以直接替换为:
<build>
<plugins>
<plugin>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-maven-plugin</artifactId>
<version>${dubbo.version}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
注:无需引入 os-maven-plugin
和 protobuf-maven-plugin
,仅需要引入 dubbo-maven-plugin
即可。
6. 移除原 REST 协议支持
在 Dubbo 3.3.x 中,Triple 协议支持了 Provider 侧原生 REST 协议的所有特性,同时移除了原 REST 协议实现的支持。
- 如果仅使用 REST 协议作为服务提供者,请修改协议名字为
tri
,使用方式无需改变,详见 Triple 3.3新特性 和 Triple REST 用户手册 - 如果需要使用 REST 协议作为服务消费者,可以添加以下依赖提供能力兼容
<dependency>
<groupId>org.apache.dubbo.extensions</groupId>
<artifactId>dubbo-rpc-rest</artifactId>
<version>3.3.0</version>
</dependency>
7. JDK 序列化
由于 JDK 原生序列化中,如果不手动添加配置,存在大量的反序列化漏洞,为了提升 Dubbo 的安全性,Dubbo 3.3.x 版本中默认不支持 JDK 序列化。
如果需要使用 JDK 序列化,可以添加以下依赖提供能力兼容,但请注意,这可能会引入安全风险。
<dependency>
<groupId>org.apache.dubbo.extensions</groupId>
<artifactId>dubbo-serialization-jdk</artifactId>
<version>3.3.0</version>
</dependency>
8. 传递依赖变更
在 Dubbo 3.3.x 中,默认不再传递以下依赖,如有需要请按需引入:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
同时,新增传递以下依赖:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
</dependency>
注:Dubbo 从 3.3.x 开始不再依赖 com.alibaba.spring:spring-context-support
实现自身能力,如果需要请自行引入。
9. Zookeeper 3.4 支持移除
由于 Zookeeper 3.4.x 已经 EOL 4 年多了,为了降低 Dubbo 的维护成本,Dubbo 3.3.x 版本中移除了对 Zookeeper 3.4.x 的支持,请迁移 Curator (如有)到 5.x 版本。
最后修改 September 13, 2024: Refactor website structure (#2860) (1a4b998f54b)