API Configuration

Configure your Dubbo application via API

As an RPC framework, Dubbo defines a complete set of API interfaces, allowing us to develop Dubbo applications based on the native API. For specific examples of using the native API to develop lightweight RPC and microservices applications, see the examples in Tutorial - API Development Mode. Its applicable scenarios fall into two categories:

  • Lightweight RPC Server & Client, typically used for simple remote call scenarios within applications, basic components, middleware, etc.
  • Microservice Applications, developing microservices directly using APIs without relying on Spring or Spring Boot; using APIs directly can also be useful for gateway or testing platform integration scenarios.

The current entry APIs primarily include Bootstrap, ServiceConfig, ReferenceConfig, etc., which are used for Dubbo application development in different scenarios.

Bootstrap API

The DubboBootstrap instance represents a Dubbo application, serving as the startup entry point for the entire Dubbo application. Based on DubboBootstrap, we can set up protocol, service, registry, metrics, etc., to register services and connect to the registry, similar to adjusting application.yml or application.properties files in Spring Boot.

It is recommended to use DubboBootstrap.start() as a centralized startup entry for the application. However, for convenience in publishing certain services independently after the process has started, Dubbo also allows direct calls to ServiceConfig.export() or ReferenceConfig.refer() methods to publish services. In this case, Service/Reference will register to the default DubboBootstrap instance, effectively similar to calling DubboBootstrap.service(…).start().

  1. import org.apache.dubbo.config.bootstrap.DubboBootstrap;
  2. import org.apache.dubbo.config.ApplicationConfig;
  3. import org.apache.dubbo.config.RegistryConfig;
  4. import org.apache.dubbo.config.ProviderConfig;
  5. import org.apache.dubbo.config.ServiceConfig;
  6. import com.xxx.DemoService;
  7. import com.xxx.DemoServiceImpl;
  8. public class DemoProvider {
  9. public static void main(String[] args) {
  10. ConfigCenterConfig configCenter = new ConfigCenterConfig();
  11. configCenter.setAddress("zookeeper://127.0.0.1:2181");
  12. // Provider protocol configuration
  13. ProtocolConfig protocol = new ProtocolConfig();
  14. protocol.setName("dubbo");
  15. protocol.setPort(12345);
  16. protocol.setThreads(200);
  17. // Note: ServiceConfig is a heavy object, encapsulating the connection with the registry and opening the service port
  18. // Provider service exposure configuration
  19. ServiceConfig<DemoService> demoServiceConfig = new ServiceConfig<>();
  20. demoServiceConfig.setInterface(DemoService.class);
  21. demoServiceConfig.setRef(new DemoServiceImpl());
  22. demoServiceConfig.setVersion("1.0.0");
  23. // Second service configuration
  24. ServiceConfig<FooService> fooServiceConfig = new ServiceConfig<>();
  25. fooServiceConfig.setInterface(FooService.class);
  26. fooServiceConfig.setRef(new FooServiceImpl());
  27. fooServiceConfig.setVersion("1.0.0");
  28. ...
  29. // Simplifying configuration assembly and controlling the startup process through DubboBootstrap
  30. DubboBootstrap.getInstance()
  31. .application("demo-provider") // Application configuration
  32. .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) // Registry configuration
  33. .protocol(protocol) // Global default protocol configuration
  34. .service(demoServiceConfig) // Add ServiceConfig
  35. .service(fooServiceConfig)
  36. .start() // Start Dubbo
  37. .await(); // Suspend wait (prevent process exit)
  38. }
  39. }
  1. import org.apache.dubbo.config.bootstrap.DubboBootstrap;
  2. import org.apache.dubbo.config.ApplicationConfig;
  3. import org.apache.dubbo.config.RegistryConfig;
  4. import org.apache.dubbo.config.ProviderConfig;
  5. import org.apache.dubbo.config.ServiceConfig;
  6. import com.xxx.DemoService;
  7. import com.xxx.DemoServiceImpl;
  8. public class DemoConsumer {
  9. public static void main(String[] args) {
  10. // Referencing remote service
  11. ReferenceConfig<DemoService> demoServiceReference = new ReferenceConfig<DemoService>();
  12. demoServiceReference.setInterface(DemoService.class);
  13. demoServiceReference.setVersion("1.0.0");
  14. ReferenceConfig<FooService> fooServiceReference = new ReferenceConfig<FooService>();
  15. fooServiceReference.setInterface(FooService.class);
  16. fooServiceReference.setVersion("1.0.0");
  17. // Simplifying configuration assembly and controlling the startup process through DubboBootstrap
  18. DubboBootstrap bootstrap = DubboBootstrap.getInstance();
  19. bootstrap.application("demo-consumer") // Application configuration
  20. .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) // Registry configuration
  21. .reference(demoServiceReference) // Add ReferenceConfig
  22. .reference(fooServiceReference)
  23. .start(); // Start Dubbo
  24. ...
  25. // Use demoService just like local bean
  26. // Get remote service interface proxy through Interface, no need to rely on ReferenceConfig object
  27. DemoService demoService = DubboBootstrap.getInstance().getCache().get(DemoService.class);
  28. demoService.sayHello("Dubbo");
  29. FooService fooService = fooServiceReference.get();
  30. fooService.greeting("Dubbo");
  31. }
  32. }

Basic Configuration

Global basic configurations can be set in DubboBootstrap, including application configuration, protocol configuration, registry, configuration center, metadata center, module, monitoring, SSL, provider configuration, consumer configuration, etc.

  1. // Registry
  2. RegistryConfig registry = new RegistryConfig();
  3. registry.setAddress("zookeeper://192.168.10.1:2181");
  4. ...
  5. // Provider protocol configuration
  6. ProtocolConfig protocol = new ProtocolConfig();
  7. protocol.setName("dubbo");
  8. protocol.setPort(12345);
  9. protocol.setThreads(200);
  10. ...
  11. // Configuration Center
  12. ConfigCenterConfig configCenter = new ConfigCenterConfig();
  13. configCenter.setAddress("zookeeper://192.168.10.2:2181");
  14. ...
  15. // Metadata Center
  16. MetadataReportConfig metadataReport = new MetadataReportConfig();
  17. metadataReport.setAddress("zookeeper://192.168.10.3:2181");
  18. ...
  19. // Metrics
  20. MetricsConfig metrics = new MetricsConfig();
  21. metrics.setProtocol("dubbo");
  22. ...
  23. // SSL
  24. SslConfig ssl = new SslConfig();
  25. ssl.setServerKeyCertChainPath("/path/ssl/server-key-cert-chain");
  26. ssl.setServerPrivateKeyPath("/path/ssl/server-private-key");
  27. ...
  28. // Provider configuration (default configuration for ServiceConfig)
  29. ProviderConfig provider = new ProviderConfig();
  30. provider.setGroup("demo");
  31. provider.setVersion("1.0.0");
  32. ...
  33. // Consumer configuration (default configuration for ReferenceConfig)
  34. ConsumerConfig consumer = new ConsumerConfig();
  35. consumer.setGroup("demo");
  36. consumer.setVersion("1.0.0");
  37. consumer.setTimeout(2000);
  38. ...
  39. DubboBootstrap.getInstance()
  40. .application("demo-app")
  41. .registry(registry)
  42. .protocol(protocol)
  43. .configCenter(configCenter)
  44. .metadataReport(metadataReport)
  45. .module(new ModuleConfig("module"))
  46. .metrics(metrics)
  47. .ssl(ssl)
  48. .provider(provider)
  49. .consumer(consumer)
  50. ...
  51. .start();

Method-level Settings

  1. ...
  2. // Method-level configuration
  3. List<MethodConfig> methods = new ArrayList<MethodConfig>();
  4. MethodConfig method = new MethodConfig();
  5. method.setName("sayHello");
  6. method.setTimeout(10000);
  7. method.setRetries(0);
  8. methods.add(method);
  9. // Referencing remote service
  10. ReferenceConfig<DemoService> reference = new ReferenceConfig<DemoService>(); // This instance is heavy, encapsulating the connection to the registry and the connection to the provider, please cache it, otherwise it may cause memory and connection leaks
  11. ...
  12. reference.setMethods(methods); // Set method-level configuration
  13. ...

Point-to-Point Direct Connection

  1. ...
  2. // This instance is heavy, encapsulating the connection to the registry and the connection to the provider, please cache it, otherwise it may cause memory and connection leaks
  3. ReferenceConfig<DemoService> reference = new ReferenceConfig<DemoService>();
  4. // For direct point-to-point connection, you can specify the target address using reference.setUrl(), and setting the URL will bypass the registry,
  5. // where the protocol corresponds to provider.setProtocol()'s value, the port corresponds to provider.setPort()'s value,
  6. // and the path corresponds to service.setPath()'s value. If the path is not set, the default path is the interface name.
  7. reference.setUrl("dubbo://10.20.130.230:20880/com.xxx.DemoService");
  8. ...

ServiceConfig

Through ServiceConfig, you can publish services directly, registering the service interface to an in-memory list and the registry. This can be very useful for scenarios that require dynamic service publishing.

Note: For ordinary application development scenarios, we recommend using DubboBootstrap API.

  1. import org.apache.dubbo.config.ApplicationConfig;
  2. import org.apache.dubbo.config.RegistryConfig;
  3. import org.apache.dubbo.config.ProviderConfig;
  4. import org.apache.dubbo.config.ServiceConfig;
  5. import com.xxx.DemoService;
  6. import com.xxx.DemoServiceImpl;
  7. public class DemoProvider {
  8. public static void main(String[] args) {
  9. // Service implementation
  10. DemoService demoService = new DemoServiceImpl();
  11. // Current application configuration
  12. ApplicationConfig application = new ApplicationConfig();
  13. application.setName("demo-provider");
  14. // Connection to registry configuration
  15. RegistryConfig registry = new RegistryConfig();
  16. registry.setAddress("zookeeper://10.20.130.230:2181");
  17. // Provider protocol configuration
  18. ProtocolConfig protocol = new ProtocolConfig();
  19. protocol.setName("dubbo");
  20. protocol.setPort(12345);
  21. protocol.setThreads(200);
  22. // Note: ServiceConfig is a heavy object, encapsulating the connection to the registry and opening the service port
  23. // Provider service exposure configuration
  24. ServiceConfig<DemoService> service = new ServiceConfig<DemoService>(); // This instance is heavy, encapsulating the connection to the registry, please cache it, otherwise it may cause memory and connection leaks
  25. service.setApplication(application);
  26. service.setRegistry(registry); // Multiple registries can use setRegistries()
  27. service.setProtocol(protocol); // Multiple protocols can use setProtocols()
  28. service.setInterface(DemoService.class);
  29. service.setRef(demoService);
  30. service.setVersion("1.0.0");
  31. // Expose and register the service
  32. service.export();
  33. // Suspend wait (prevent process exit)
  34. System.in.read();
  35. }
  36. }

ReferenceConfig

Through ReferenceConfig, you can reference remote services and subscribe to service interfaces from the registry. This can be very useful for scenarios that require dynamic service publishing.

Note: For ordinary application development, we recommend using DubboBootstrap API.

  1. import org.apache.dubbo.config.ApplicationConfig;
  2. import org.apache.dubbo.config.RegistryConfig;
  3. import org.apache.dubbo.config.ConsumerConfig;
  4. import org.apache.dubbo.config.ReferenceConfig;
  5. import com.xxx.DemoService;
  6. public class DemoConsumer {
  7. public static void main(String[] args) {
  8. // Current application configuration
  9. ApplicationConfig application = new ApplicationConfig();
  10. application.setName("demo-consumer");
  11. // Connection to registry configuration
  12. RegistryConfig registry = new RegistryConfig();
  13. registry.setAddress("zookeeper://10.20.130.230:2181");
  14. // Note: ReferenceConfig is a heavy object, encapsulating the connection to the registry and the connection to the service provider
  15. // Referencing remote service
  16. ReferenceConfig<DemoService> reference = new ReferenceConfig<DemoService>(); // This instance is heavy, encapsulating the connection to the registry and to the provider, please cache it, otherwise it may cause memory and connection leaks
  17. reference.setApplication(application);
  18. reference.setRegistry(registry); // Multiple registries can use setRegistries()
  19. reference.setInterface(DemoService.class);
  20. reference.setVersion("1.0.0");
  21. // Use demoService just like local bean
  22. // Note: This proxy object encapsulates all communication details and is relatively heavy, please cache for reuse
  23. DemoService demoService = reference.get();
  24. demoService.sayHello("Dubbo");
  25. }
  26. }

Multi-instance Deployment

The background of multi-instance deployment originates from the large-scale application deployment scenario of Dubbo within Alibaba Group. The main problems encountered by Alibaba Group include:

  1. There are many middleware frameworks within Alibaba Group, each providing various class loading methods. Different business parties expect the configuration and other information within the same application to be mutually isolated.
  2. Some business parties’ custom logic requires support for dynamic hot deployment mode, specifically reflected in the dynamic destruction of a certain virtual environment, which necessitates a more refined management of Dubbo’s lifecycle.
  3. Various frameworks within Alibaba Group have been customized for the Spring container and need to allow Dubbo to support scenarios where multiple Spring Contexts independently manage their lifecycles.

Multi-instance architecture diagram

The entire design of Dubbo multi-instances 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 certain rules:

  1. Framework and Framework are completely isolated, equivalent to using two completely different Dubbo instances.
  2. Applications are isolated by application name, while sharing Protocol and Serialization layers to some extent, aiming to allow multiple applications to be hosted on the same dubbo port (20880), with each application reporting address information independently.
  3. Modules can be user-defined isolated, which can be either a state in the hot deployment period or a Spring Context’s Context. Through Modules, users can manage the granularity of Dubbo’s lifecycle at its minimal.

To achieve Dubbo’s multi-instance implementation, the most significant change made to the Dubbo framework is modifying most of the logic for obtaining parameters from static variables. The most notable change is the URL object used for parameter transfer within Dubbo now carries the ScopeModel state, which corresponds to the specific data-bearing objects of the aforementioned three-layer model. For more implementation principles and design details about multi-instances, please refer to Source Architecture - Multi-instance Design and Implementation.

  1. ServiceConfig<DemoService> service = new ServiceConfig<>();
  2. service.setInterface(DemoService.class);
  3. service.setRef(new DemoServiceImpl());
  4. ReferenceConfig<DemoService> reference1 = new ReferenceConfig<>();
  5. reference1.setInterface(DemoService.class);
  6. ReferenceConfig<DemoService> reference2 = new ReferenceConfig<>();
  7. reference2.setInterface(DemoService.class);
  8. // Create a launcher (automatically create a new ApplicationModel)
  9. DubboBootstrap bootstrap1 = DubboBootstrap.newInstance();
  10. // Specify application name
  11. bootstrap1.application(new ApplicationConfig("dubbo-demo-app-1"))
  12. .registry(new RegistryConfig("nacos://localhost:8848"))
  13. // Create a module
  14. .newModule()
  15. // Publish service within the module
  16. .service(service)
  17. .endModule()
  18. // Create another module
  19. .newModule()
  20. // Subscribe to service within the module
  21. .reference(reference1)
  22. .endModule()
  23. .start();
  24. // Create another launcher (automatically create a new ApplicationModel)
  25. DubboBootstrap bootstrap2 = DubboBootstrap.newInstance();
  26. // Specify application name
  27. bootstrap2.application(new ApplicationConfig("dubbo-demo-app-2"))
  28. .registry(new RegistryConfig("nacos://localhost:8848"))
  29. // Create a module
  30. .newModule()
  31. // Subscribe to service within the module
  32. .reference(reference2)
  33. .endModule()
  34. .start();
  35. // stub1 and stub2 are two independent subscriptions, completely isolated
  36. // Subscribed stub
  37. DemoService stub1 = reference1.get();
  38. System.out.println(stub1.sayHello("Hello World!"));
  39. // Subscribed stub
  40. DemoService stub2 = reference2.get();
  41. System.out.println(stub2.sayHello("Hello World!"));
  42. bootstrap1.stop();
  43. bootstrap2.stop();

This example exposes a service of DemoService, provided by the application dubbo-demo-app-1. Simultaneously, we created two subscriptions, one in the application dubbo-demo-app-1 and another in dubbo-demo-app-2, and then invoked the subscriptions to obtain the expected results.

It is worth noting that although the service information for both subscriptions is entirely consistent, after the multi-instance transformation, these two subscriptions are completely isolated for the consumer side, meaning that the latest version of Dubbo now supports creating multiple subscriptions by changing parameters in a way similar to tuples.

Feedback

Was this page helpful?

Yes No

Last modified September 30, 2024: Update & Translate Overview Docs (#3040) (d37ebceaea7)