Upgrade from 3.2 to 3.3

Dubbo 3.3 Upgrade and Compatibility Guide

For the vast majority of users, upgrading to Dubbo 3.3.0 is completely smooth, requiring only a change in the dependency version.

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>3.3.0</version>
</dependency>

or

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>3.3.0</version>
</dependency>

Compatibility Checklist

1. Default Serialization Switch

Starting with Dubbo 3.3.0, the default serialization method changes from fastjson2 to hessian2. For applications upgrading to 3.3.0, Dubbo will automatically attempt to use hessian2 for serialization.

Q1: Why switch the default serialization method?

hessian2 was the default serialization in Dubbo versions 3.1.x and below, proven stable and compatible in long-term production. After evaluating backward compatibility and long-term maintainability, the Dubbo team decided to upgrade hessian-lite to the latest hessian4, supporting JDK17 and JDK21.

After upgrading to Dubbo 3.3.0, the dependent hessian-lite version will be upgraded to 4.0.x, including the following changes:

  • Sync hessian to the upstream 4.0.66 version
  • Fix compatibility issues due to class visibility in JDK17 and JDK21
  • Support features like Record, ImmutableCollections, etc. from JDK9+

Q2: Will this affect interoperability with lower versions of Dubbo?

There might be impacts in some scenarios, detailed as follows:

  1. When a Dubbo 3.3.x Consumer communicates with a Dubbo 3.2.x Provider, it defaults to the fastjson2 priority strategy from Dubbo 3.2.x, with no compatibility issues.
  2. When a Dubbo 3.3.x Consumer communicates with a Dubbo 3.1.x or lower version Provider, it defaults to the fastjson2 priority strategy from Dubbo 3.2.x, with no compatibility issues.
  3. When a Dubbo 3.2.x Consumer communicates with a Dubbo 3.3.x Provider, it defaults to the hessian2 priority strategy from Dubbo 3.3.x, potentially causing compatibility issues in scenarios with a JDK >= 17. It is recommended to upgrade according to the best practices in Q3.
  4. When a Dubbo 3.1.x or lower version Consumer communicates with a Dubbo 3.3.x Provider, it defaults to the hessian2 priority strategy from Dubbo 3.3.x, also potentially causing compatibility issues in scenarios with a JDK >= 17. It is recommended to upgrade according to the best practices in Q3.

Refer to Serialization Protocol Upgrade Guide for principles.

Q3: What are the best practices for upgrading serialization?

  1. When upgrading from Dubbo 3.2.x to 3.3.x, it is recommended to configure prefer-serialization to fastjson2,hessian2 to maintain consistency with 3.2.x. After completing the full cluster upgrade, this configuration can be removed to use hessian2 serialization.
  2. When upgrading from Dubbo 3.1.x or lower to 3.3.x, no configuration for prefer-serialization is needed, but avoid upgrading JDK concurrently to avoid compatibility issues.

Q4: What if I still want to use fastjson2?

If you do not want to use hessian2, you can configure prefer-serialization to fastjson2 to override the default configuration. (e.g., dubbo.provider.prefer-serialization=fastjson2,hessian2)


2. Not Registering Using register=false Will Prevent Manual Registration Through QoS

If dubbo.registry.register=false is configured in the registry center configuration or the service configuration specifies dubbo.provider.register=false:

  1. In Dubbo versions 3.2.x and earlier, by default, Dubbo does not automatically register, and using the QoS command (curl http://127.0.0.1:22222/online) can achieve registration.
  2. In Dubbo 3.3.x, by default, Dubbo does not automatically register, and using the QoS command will also not register.

Q1: Why make this adjustment?

To prevent some users from using graceful go-live and isolated environment configurations inconsistently, causing cross-environment erroneous registrations, register=false is defined as never register, while delay=-1 and -Ddubbo.application.manual-register=true is defined as delayed until manual registration.

Q2: What are the best practices for achieving graceful go-live?

In simple terms, two configurations are needed: delay=-1 and -Ddubbo.application.manual-register=true.

delay=-1 allows the specified service to undergo graceful go-live:

  1. If you need all services to undergo graceful go-live, configure dubbo.provider.delay=-1.
  2. If only certain services need graceful go-live, configure delay=-1 in the specified service configuration.

-Ddubbo.application.manual-register=true enables manual registration: For machines that need to perform graceful go-live, configure the JVM parameter -Ddubbo.application.manual-register=true.

Complete the startup script: For machines that need graceful go-live, after the startup script finishes, actively call the QoS command curl http://127.0.0.1:22222/online for registration.

Considerations:

  1. Use a global codebase that configures delay=-1 for services needing graceful go-live in both production and testing environments.
  2. Only configure -Ddubbo.application.manual-register=true in the production environment, leaving the testing environment unconfigured to ensure automatic registration of services in the testing environment.

3. Nacos Compatibility Subscription Default Disabled

Starting with Dubbo version 3.3.x, it will no longer subscribe to compatible service names from Dubbo version 2.7.3 and earlier. If you still need to subscribe, please configure -Dnacos.subscribe.legacy-name=true.

Q1: Why make this adjustment?

In Dubbo versions 2.7.3 and earlier, when Dubbo services were registered in Nacos, the subscription format was providers(:{interfaceName})(:{version})(:{group}), where if any field was empty, the preceding : would also be omitted, leading to non-unique subscriptions and inability to subscribe accurately.

For example:

  1. Interface Name: com.foo.BarService, Version: 1.0.0, Group: baz, Subscription Name: providers:com.foo.BarService:1.0.0:baz
  2. Interface Name: com.foo.BarService, Version: empty, Group: baz, Subscription Name: providers:com.foo.BarService:baz
  3. Interface Name: com.foo.BarService, Version: baz, Group: empty, Subscription Name: providers:com.foo.BarService:baz

As mentioned, the subscription names for 2 and 3 are identical, but they actually represent different services.

To resolve this issue, in Dubbo versions 2.7.4 and later, subscription names will change to providers:({interfaceName}):({group}):({version}), ensuring the uniqueness of subscription names.

For example:

  1. Interface Name: com.foo.BarService, Version: 1.0.0, Group: baz, Subscription Name: providers:com.foo.BarService:1.0.0:baz
  2. Interface Name: com.foo.BarService, Version: empty, Group: baz, Subscription Name: providers:com.foo.BarService::baz
  3. Interface Name: com.foo.BarService, Version: baz, Group: empty, Subscription Name: providers:com.foo.BarService:baz:

4. Dubbo Spring Boot Starters Update

In Dubbo 3.3.x, Dubbo Spring Boot Starters provide more Starter dependencies for convenient dependency management.

Additionally: To comply with Spring’s naming conventions, starting from version 3.3.0, the observable related Starter’s artifactId will be renamed from dubbo-spring-boot-observability-starter to dubbo-observability-spring-boot-starter.

Q1: What Starters are available in Dubbo 3.3.x?

Below is a list of starters provided by the official Dubbo community (version 3.3.0+) for quick use in Spring Boot applications:

  • dubbo-spring-boot-starter: Manages core Dubbo dependencies for recognizing application.properties or application.yml configurations starting with dubbo., and scans annotations like @DubboService.
  • dubbo-spring-boot-starter3: Manages core Dubbo dependencies, same as dubbo-spring-boot-starter, supports Spring Boot 3.2.
  • dubbo-nacos-spring-boot-starter: Manages nacos-client and other dependencies, for use with Nacos as a registry and configuration center.
  • dubbo-zookeeper-spring-boot-starter: Manages zookeeper, curator and other dependencies for use with Zookeeper as a registry and configuration center (uses Zookeeper Server version 3.4 and below).
  • dubbo-zookeeper-curator5-spring-boot-starter: Manages zookeeper, curator5 and other dependencies for use with Zookeeper as a registry and configuration center.
  • dubbo-sentinel-spring-boot-starter: Manages sentinel and other dependencies for use with Sentinel for rate limiting and downgrading.
  • dubbo-seata-spring-boot-starter: Manages seata and other dependencies for use with Seata as a distributed transaction solution.
  • dubbo-observability-spring-boot-starter: Adding this dependency will automatically enable Dubbo’s built-in metrics collection, usable for future monitoring systems like Prometheus and Grafana.
  • dubbo-tracing-brave-spring-boot-starter: Manages brave/zipkin, micrometer, and other related dependencies for use with Brave/Zipkin as a tracer to export trace information to Zipkin.
  • dubbo-tracing-otel-otlp-spring-boot-starter: Manages brave/zipkin, micrometer, and other related dependencies for use with OpenTelemetry as a tracer to export trace information to OTlp Collector.
  • dubbo-tracing-otel-zipkin-spring-boot-starter: Manages brave/zipkin, micrometer, and other related dependencies for use with OpenTelemetry as a tracer to export trace information to Zipkin.

5. Migration of dubbo-compiler and dubbo-native-plugin to dubbo-maven-plugin

In version 3.3, Dubbo removed dubbo-native-plugin, and all functionalities related to dubbo-native-plugin will be migrated to dubbo-maven-plugin. Additionally, the support for dubbo-compiler has also been added in dubbo-maven-plugin.

For more details on dubbo-maven-plugin, please refer to Configuration Details.

Q1: Why make this migration and adjustment?

  1. To enhance user experience, all future Dubbo-related Maven plugin capabilities will be uniformly provided by dubbo-maven-plugin. This simplifies usage and integration for Dubbo users, avoiding the need to depend on multiple plugins for different features.
  2. It is more conducive to future maintenance and feature enhancement of Dubbo’s maven plugin capabilities.

Q2: How to migrate configurations?

  1. When using Native Image, the original configuration was:

<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>

It needs to be replaced with:

<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>

Note: Only replace artifactId.

  1. When using Triple + Protobuf, the original configuration was:
<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>

It can be directly replaced with:

<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>

Note: No need to introduce os-maven-plugin and protobuf-maven-plugin, only introduce dubbo-maven-plugin.


6. Removal of Original REST Protocol Support

In Dubbo 3.3.x, the Triple protocol supports all features of the native REST protocol on the Provider side, while removing support for the original REST protocol implementation.

  1. If you are using the REST protocol solely as a service provider, please change the protocol name to tri. The usage mode remains unchanged, see Triple 3.3 New Features and Triple REST User Guide.
  2. If you need to use the REST protocol as a service consumer, you can add the following dependency for compatibility.
<dependency>
    <groupId>org.apache.dubbo.extensions</groupId>
    <artifactId>dubbo-rpc-rest</artifactId>
    <version>3.3.0</version>
</dependency>

7. JDK Serialization

Due to numerous deserialization vulnerabilities in JDK’s native serialization if configurations are not manually added, to enhance Dubbo’s security, the default support for JDK serialization is disabled in Dubbo 3.3.x.

If you need to use JDK serialization, you can add the following dependency for compatibility, but please note that this may introduce security risks.

<dependency>
    <groupId>org.apache.dubbo.extensions</groupId>
    <artifactId>dubbo-serialization-jdk</artifactId>
    <version>3.3.0</version>
</dependency>

8. Transitive Dependency Changes

In Dubbo 3.3.x, the following dependencies are no longer transitively included by default, please include them as needed:

    <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>

At the same time, the following dependencies will be transitively included:

    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java</artifactId>
    </dependency>
    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java-util</artifactId>
    </dependency>

Note: Starting from 3.3.x, Dubbo no longer depends on com.alibaba.spring:spring-context-support to implement its capabilities. Please include it yourself if needed.


9. Removal of Zookeeper 3.4 Support

Since Zookeeper 3.4.x has been EOL for over 4 years, to reduce Dubbo’s maintenance costs, support for Zookeeper 3.4.x has been removed in Dubbo 3.3.x. Please migrate Curator (if any) to version 5.x.