Dubbo is an open source RPC call framework from Alibaba. The implementation complexity of RPC remote calls can be greatly simplified and the implementation of business capabilities can be more focused. Remote service interfaces can be used just like local API calls.

This article will document some of the key information about Dubbo and show you how to use Dubbo in your code.

1. Key concepts of Dubbo

1.1 Basic principles of DUBBO

A basic networking and schematic diagram of Dubbo is as follows (picture taken from network) :

Node roles:

Provider: exposes the service Provider of the service. Consumer: Service Consumer that invokes the remote service. Registry: A Registry where services are registered and discovered. Monitor: monitors The Times and time of service invocation.

Please refer to the official Dubbo documentation for more details.

1.2 DUBBO’s support for the agreement

1. Dubbo can select a protocol

  1. DubboProtocol, adoptedNIOReuse a single long connection, and useThe thread pool** (recommended) ** [Problem: In large file transfers, a single connection can become a bottleneck]
  2. RmiProtocols are available with nativeRMIInteroperable based onTCPThe agreement. [Problem: Occasionally the connection fails and the Stub needs to be rebuilt]
  3. HessianProtocols are available with nativeHessianInteroperable based onHTTPProtocol [requires hessian.jar support, HTTP short connection overhead]

2. Dubbo can be serialized in a variety of ways

  1. Hessian Serialization, good performance, multi-language support
  2. Dubbo Serialization, by not transmitting the class meta information of POJOs, the performance is good when a large number of POJOs are transmitted.
  3. Json Serialization, plain text, can be parsed across languages, FastJson is used by default
  4. Java SerializationJava native support [Problem: poor performance]

3. The default protocol is Dubbo, which is serialized as Hessian

1.3 Differences between service ports and Dubbo protocol ports

When a process starts, it has a port, such as the SpringBoot service. In application. Properties, a server.port value is set.

Dubbo is an independent protocol. When providing services externally, you need to specify a port corresponding to dubbo. The two ports need to be separated, not the same, which is easy for beginners to confuse.

Dubbo port can be specified in two ways:

    1. Specified in the XML
<! Expose service on port 20880 with dubbo
 <dubbo:protocol name="dubbo" port="20880" ></dubbo:protocol>
Copy the code
    1. SpringBoot engineering, code specified
    @Bean
    public ProtocolConfig protocolConfig(a) {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setPort(8811);
        protocolConfig.setName("dubbo");
        return protocolConfig;
    }
Copy the code

2 Dubbo service code implementation

In complex and large distributed systems, service registries are usually required. By default, Dubbo works with Zookeeper as the registry and can be connected to other distributed service registries. It is recommended to use Ali’s open source Nacos as the matching registry for Dubbo. For details, please refer to my other article “Playing with Nacos! Instead of Eureka as configuration center and Registry”.

The following sample code demonstrates a scenario in which a consumer makes a call directly to a service provider without using a registry, with the main focus on how to integrate and use Dubbo.

2.1 SpringBoot integrates Maven dependencies corresponding to Dubbo

The Dubbo package needs to be imported (for example, no registry is used, so zooKeeper-related packages are not needed).

    <dependency>
        <groupId>com.alibaba.spring.boot</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.0.0</version>
    </dependency>
Copy the code

2.2 Service Provider Service Provider

2.2.1 Implement defined RPC interfaces that need to be opened to the outside world, and implement specific implementation logic

The @component Component will automatically Spring host the service according to SpringBoot logic and complete the initial load. 2, @ com. Alibaba. Dubbo. Config. The annotation. The Service is the provided dubbo, said this is need to dubbo external services.

As follows:

@Component
@com.alibaba.dubbo.config.annotation.Service(timeout = 5000)
public class RpcDemoServiceImpl implements RpcDemoService {

    @Override
    public String queryCurrentTime(String queryId) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        String formattedDate = simpleDateFormat.format(new Date());
        System.out.println(queryId + " called, current time is: " + formattedDate);
        return queryId + "|"+ formattedDate; }}Copy the code

2.2.2 The Dubbo directory to be scanned is defined in the Startup class

@springBootApplication specifies that a regular SpringBoot application should be started. 2, @ EnableDubbo open support for Dubbo, and specify the corresponding directory, will scan the specified directory of class, to find all the @ com. Alibaba. Dubbo. Config. The annotation. The Service identification needs to release to Dubbo Service interface classes.

As follows:

@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.vzn.local.dubbo.provider.service"})
public class ProviderApp {
    public static void main(String[] args) { SpringApplication.run(ProviderApp.class); }}Copy the code

2.2.3 Specifying Dubbo Settings

Either way, it can be written directly in code or specified in a configuration file.

2.2.3.1 Specified by Bean injection in code

Key definitions of Dubbo are injected via @bean. As with the XML configuration, specific values are set here in the form of the corresponding JAVA object.

ApplicationConfig corresponds to the configuration information of the
node in XML.

2. ProtocolConfig corresponds to the configuration information of the dubbo:protocol /> node in XML.

RegistryConfig corresponds to the configuration information of the
node in XML.

Example code is as follows:

@Configuration
public class DubboConfig {

    @Bean
    public ApplicationConfig applicationConfig(a) {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-provider");
        return applicationConfig;
    }

    @Bean
    public ProtocolConfig protocolConfig(a) {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setPort(8811);
        protocolConfig.setName("dubbo");
        return protocolConfig;
    }

    @Bean
    public RegistryConfig registryConfig(a) {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("N/A");
        registryConfig.setRegister(false);

/ / registryConfig. SetAddress (" zookeeper: / / 127.0.0.1:2181 ");
        returnregistryConfig; }}Copy the code
2.2.3.2 throughapplication.propertiesIn the configuration
spring.application.name=dubbo-provider
server.port=28811

# dubbo config
dubbo.application.id=dubbo-provider
dubbo.application.name=dubbo-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=8811
dubbo.registry.address=N/A
Copy the code

At this point, a simple SpringBoot logic that integrates dubbo with code and annotations is ready to boot.

Note:

  1. The local test DEMO is directly invoked without setting a registry, so the address specified in RegistryConfig isN/A;
  2. In actual use, ifzookeeperAs the registry, set this parameter tozookeeperThe correspondingIPandportValue. (of course,Or you can chooseNacosUse as a configuration + registry, recommended)

Service Consumer

2.3.1 Local Reference RPC service interface to implement the corresponding Service class

To implement a simple SpringBoot project, in conventional @ the class of Service identification, the introduction of remote RPC Service corresponding to the local API interface, and through the @ com. Alibaba. Dubbo. Config. The annotation. The Reference annotations are identified, This annotation means that the bean will call the method in the remote real implementation class via RPC and return the execution result.

This is an advantage of Dubbo framework, will all the underlying logic to encapsulate blocked, making business code used in RPC interface, can be carried out in accordance with the local API way direct call, greatly reduces the coding difficulty, allowing developers to focus on their own business, without having to focus on specific how should the RPC calls to the remote server.

Example code is as follows:

@org.springframework.stereotype.Service
public class RpcConsumerService {

// @Reference
// private RpcDemoService rpcDemoService;

    // Both parameters specified in the following ways can be called successfully
    @Reference(protocol = "dubbo", url = "172.31.236.79:8811", interfaceClass = RpcDemoService.class)
    / / @ Reference [url = "dubbo: / / 172.31.236.79:8811)"
    private RpcDemoService rpcDemoService;

    public String getTime(String requestId) {
        returnrpcDemoService.queryCurrentTime(requestId); }}Copy the code

Description:

The local DEMO code has no registry and is directly connected. Therefore, the url information (specific IP address of the directly connected service and Dubbo protocol port) is specified in @Reference.

2.3.2 Enable Dubbo support in startup class

As follows:

@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.vzn.local.dubbo.consumer.service"})
public class ConsumerApp {
    public static void main(String[] args) { SpringApplication.run(ConsumerApp.class); }}Copy the code

2.3.3 Manually injecting Dubbo configuration information into the code

The following is similar to provider, but slightly different:

@Configuration
public class DubboConfig {

    @Bean
    public ApplicationConfig applicationConfig(a) {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-consumer");
        return applicationConfig;
    }

    @Bean
    public RegistryConfig registryConfig(a) {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("N/A");
/ / registryConfig. SetAddress (" zookeeper: / / 127.0.0.1:2181 ");
        registryConfig.setClient("curator");
        return registryConfig;
    }

    @Bean
    public ConsumerConfig consumerConfig(a) {
        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setTimeout(3000);
        returnconsumerConfig; }}Copy the code

Or configure it directly in application.properties:

spring.application.name=dubbo-consumer server.port=28812 # dubbo config dubbo.application.id=dubbo-consumer dubbo.application.name=dubbo-consumer dubbo.protocol.name=dubbo dubbo.registry.address=N/A dubbo.registry.client=curator  dubbo.server=false dubbo.consumer.timeout=3000Copy the code

The consumer service adds a configuration called ConsumerConfig, which in this example simply defines a call-side timeout value.

2.3.4 Provide a Controller service for test calls

As usual with SpringBoot, a Controller service is provided to trigger test use.

@RestController
@RequestMapping("/demo/dubbo")
public class RpcController {

    @Resource(name = "rpcConsumerService")
    private RpcConsumerService service;

    @GetMapping("/get/time/{requestId}")
    public String getTime(@PathVariable("requestId") String requestId) {
        String time = service.getTime(requestId);
        System.out.println("RPC call the getTime result:" + time);
        returntime; }}Copy the code

At this point, a simple SpringBoot implementation of the Dubbo client service is complete, and after startup, the Controller service can be invoked to verify the effect.

2.4 Test call validation

We can start the Provider and Consumer services and then send a notification in the browser to trigger the Consumer service:

http://127.0.0.1:28812/demo/dubbo/get/time/1
Copy the code

Test results:

1 | 14:21:11 2019-12-23. 463Copy the code

It can be found that when the method in consumer is executed, RPC in the Consumer process calls the corresponding method in the provider process and returns the specific execution result of the method. The test verification is completed.


Welcome to pay attention to my public account “Architecture Record”, the first time to push original technical articles, can also interact with the discussion of communication technology.