Java’s static variable capability allows binding behaviors holding object references to classes, providing significant convenience to developers. Implementation solutions for design patterns like Singleton and Factory rely on static variables. By using static variables, developers can easily access needed object information anytime, anywhere.
public class Test {
public static Object obj;
}
Test.obj = xxx;
In the long-standing development of the Dubbo framework, static variables have been widely used, such as using a globally shared ConfigManager to store global configuration information, and ServiceRepository to store service information. This design is optimal from the perspective of centralized management of configuration or parameter acquisition. In all versions before Dubbo 2.7, runtime configuration information needed by Dubbo was accessed through global static variables, uniquely identified via the RPC service triplet (interface + version + group).
However, with the growing user base of Dubbo and challenges brought by the HSF3 framework, which uses Dubbo as its core, new requirements have emerged.
For open-source users, the community feedback mainly includes:
For large-scale implementations within Alibaba Group, the main challenges include:
Based on these reasons, we decided to refactor Dubbo’s lifecycle in early August. After a month of intensive development, the community version now fully supports multi-instantiation, and Dubbo’s lifecycle has become clearer.
The entire design of Dubbo’s multi-instance is configured according to a three-layer model: Framework layer, Application layer, and Module layer. Based on this three-layer mechanism, we can isolate Dubbo according to specific rules:
To achieve Dubbo multi-instantiation, many of the logic changes within the Dubbo framework involved altering the processes that obtained parameters from static variables. The most notable change is that the URL object used for parameter passing within Dubbo now carries ScopeModel status, corresponding to the specific data carrier of the mentioned three-layer model.
The multi-instance refactoring of Dubbo is largely seamless for most users. The modified DubboBootstrap has been transformed into an independent launcher, allowing users to customize the use of multiple instances.
Here’s a simple example of using multiple instances.
ServiceConfig<DemoService> service = new ServiceConfig<>();
service.setInterface(DemoService.class);
service.setRef(new DemoServiceImpl());
ReferenceConfig<DemoService> reference1 = new ReferenceConfig<>();
reference1.setInterface(DemoService.class);
ReferenceConfig<DemoService> reference2 = new ReferenceConfig<>();
reference2.setInterface(DemoService.class);
// Create a launcher (automatically create a new ApplicationModel)
DubboBootstrap bootstrap1 = DubboBootstrap.newInstance();
// Specify application name
bootstrap1.application(new ApplicationConfig("dubbo-demo-app-1"))
.registry(new RegistryConfig("nacos://localhost:8848"))
// Create a module
.newModule()
// Publish service within the module
.service(service)
.endModule()
// Create a module
.newModule()
// Subscribe to service within the module
.reference(reference1)
.endModule()
.start();
// Create a launcher (automatically create a new ApplicationModel)
DubboBootstrap bootstrap2 = DubboBootstrap.newInstance();
// Specify application name
bootstrap2.application(new ApplicationConfig("dubbo-demo-app-2"))
.registry(new RegistryConfig("nacos://localhost:8848"))
// Create a module
.newModule()
// Subscribe to service within the module
.reference(reference2)
.endModule()
.start();
// stub1 and stub2 are two independent subscriptions, isolated from each other.
// Subscribed stub
DemoService stub1 = reference1.get();
System.out.println(stub1.sayHello("Hello World!"));
// Subscribed stub
DemoService stub2 = reference2.get();
System.out.println(stub2.sayHello("Hello World!"));
bootstrap1.stop();
bootstrap2.stop();
This example exposes a DemoService, provided by the application dubbo-demo-app-1. At the same time, we create two subscriptions, in the applications dubbo-demo-app-1 and dubbo-demo-app-2, and we call both subscriptions to achieve the expected results.
It is worth noting that although the service information of the two subscriptions is completely identical, after the multi-instantiation modification, these subscriptions are entirely isolated from the consumer’s perspective. The latest version of Dubbo now supports the behavior of creating multiple subscriptions by changing parameters, even when the triplets are identical.