3.2 升级至 3.3
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)
