The past and present life and application practice of Dubbo, a distributed service governance framework

Keywords: Java

Dubbo's background

Dubbo has been open source for nearly 10 years and has been widely used in major domestic enterprises. What magic is it worth pursuing? This article gives you a detailed description.

Requirements of large-scale service for service governance

When enterprises begin large-scale service, the disadvantages brought by remote communication become more and more obvious. for instance

  1. The service link becomes longer. How to track and monitor the service link?
  2. The large-scale clustering of services makes it necessary for services to rely on a third-party registry to solve the problems of service discovery and service perception
  3. For exceptions between service communications, there needs to be a protection mechanism to prevent a node failure from causing large-scale system failure, so there should be a fault-tolerant mechanism
  4. The large-scale cluster of services will be the client, and the load balancing mechanism needs to be introduced to realize request distribution

For these requirements for service governance, the traditional RPC technology is a little weak in such a scenario. Therefore, many enterprises began to develop their own RPC framework, such as Alibaba's HSF and Dubbo; JD's JSF framework, Dangdang's dubbox, Sina's motan, ant gold's sofa, etc

Companies with technology output capability will develop rpc frameworks suitable for their own scenarios, either from 0 to 1, or based on existing ideas and combined with the company's business characteristics. Companies without technology output capability will give priority to those mature open source frameworks when meeting the needs of service governance. Dubbo is one of them

Dubbo is mainly a distributed service governance solution, so what is service governance? Service governance is mainly a solution to the problems of routing, load balancing, fault tolerance mechanism and service degradation between services after large-scale service. Dubbo not only realizes remote service communication, but also solves the functions of service routing, load, degradation and error tolerance.

Dubbo's history

Dubbo is a distributed service governance framework used internally by Alibaba. It was opened in 2012. Because Dubbo has been verified and relatively mature within the company, it has been used by many Internet companies in a very short time. In addition, many technical giants from Alibaba have entered various start-up companies as technical frameworks, With Dubbo as the main RPC framework, Dubbo soon became the first choice of many Internet companies. In addition, when applying Dubbo, many companies will optimize and improve based on their own business characteristics, so many versions have been derived, such as JD's JSF, Sina's Motan and Dangdang's dubbox

In October 2014, Dubbo stopped maintenance. Later, in September 2017, Ali announced the restart of Dubbo and made preparations for long-term investment in Dubbo. During this period, Dubbo has been updated a lot. The current version has reached 2.7

On January 8, 2018, Liang Fei, one of the founders of Dubbo, revealed that Dubbo 3.0 was under construction in the Dubbo exchange group. Dubbo 3.0 kernel is completely different from Dubbo 2.0, but compatible with Dubbo 2.0. Dubbo 3.0 will support optional Service Mesh

In February 2018, Dubbo donated to Apache. In addition, due to alibaba's improvement of the Spring Cloud Alibaba ecosystem and the Spring Cloud team's support for alibaba's entire service governance ecosystem, Dubbo will still be the first choice for most domestic companies in the future.

Dubbo's overall architecture

Use of Dubbo

First, build two maven projects

  • user-service

    • user-service-api
    • user-service-provider
  • user-service-consumer

user-service-api

User service is a public contract for providing services, which provides external services of user service.

public interface ILoginService {

    String login(String username,String password);
}

user-service-provider

In the user service provider service, provide the implementation of ILoginService

public class LoginServiceImpl implements ILoginService{
    @Override
    public String login(String username, String password) {
        if(username.equals("admin")&&password.equals("admin")){
            return "SUCCESS";
        }
        return "FAILED";
    }
}

user-service-consumer

public class App 
{
    public static void main( String[] args ){
        ILoginService loginService=null;

        System.out.println(loginService.login("admin","admin"));
    }
}

Here's the problem. Now, as a service consumer, how can the user service consumer call the remote service user service provider?

According to the previous principle of service remote communication, the service provider must publish the service to the network and provide the corresponding access protocol. The service consumer must access based on this protocol.

At this time, dubbo middleware comes in handy. Its most basic function is to provide service publishing and remote access.

Introducing Dubbo publishing services

  • Introducing dubbo dependency package

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.8</version>
    </dependency>
  • Add the application.xml file in the / src/main/resource/META-INF/spring directory

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
        <!-- Provider application information for calculating dependencies -->
        <dubbo:application name="user-service"/>
        <!-- use multicast Broadcast registry service address -->
        <dubbo:registry address="N/A" />
        <!-- use dubbo The protocol exposes services on port 20880 -->
        <dubbo:protocol name="dubbo" port="20880" />
        <!-- Declare the service interfaces that need to be exposed -->
        <dubbo:service interface="com.gupaoedu.demo.ILoginService" ref="loginService" />
        <!-- And local bean Implement services like -->
        <bean id="loginService" class="com.gupaoedu.demo.LoginServiceImpl" />
    
    </beans>
  • Start service

    public class App 
    {
        public static void main( String[] args ){
            Main.main(args);
        }
    }
  • After successful startup, you will see the following log on the console

    information:  [DUBBO] Export dubbo service com.gupaoedu.demo.ILoginService to url dubbo://192.168.1.104:20880/com.gupaoedu.demo.ILoginService?anyhost=true&application=user-service&bind.ip=192.168.1.104&bind.port=20880&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.gupaoedu.demo.ILoginService&methods=login&pid=24280&release=2.7.8&side=provider&timestamp=1596550697070, dubbo version: 2.7.8, current host: 192.168.152.1
     August 04, 2020 10:18:17 afternoon org.apache.dubbo.remoting.transport.AbstractServer info
     information:  [DUBBO] Start NettyServer bind /0.0.0.0:20880, export /192.168.1.104:20880, dubbo version: 2.7.8, current host: 192.168.152.1

Through the above steps, it means that ILoginService has been published to the network. Based on the form of NettyServer, it listens to port 20880 by default

Introducing dubbo to service consumers

  • Add jar package dependency

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.8</version>
    </dependency>
  • Add the application.xml file in the / src/main/resources/META-INF/spring directory

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
        <!-- Provider application information for calculating dependencies -->
        <dubbo:application name="user-service-consumer"/>
        <!-- use multicast Broadcast registry service address -->
        <dubbo:registry address="N/A" />
        <dubbo:reference id="loginService" interface="com.gupaoedu.demo.ILoginService"/>
    </beans>
  • Modify main method

    • Load the spring configuration file through ApplicationContext
    • Get a bean of ILoginService from the container
    public class App 
    {
        public static void main( String[] args ){
            ILoginService loginService=null;
            ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:META-INF/spring/application.xml");
            loginService=applicationContext.getBean(ILoginService.class);
    
            System.out.println(loginService.login("admin","admin"));
        }
    }

Specifies the url of the service provider

After the above configuration is completed, the following errors will be prompted after running the project

IllegalStateException: No such any registry to reference com.gupaoedu.demo.ILoginService on the consumer 192.168.152.1 use dubbo version 2.7.8, please config <dubbo:registry address="..." /> to your spring config.

The reason is that the registry specified by dubbo:registry is N/A, which means that there is no registry configured.

Secondly, we have not clearly indicated where the service provider is. Therefore, there are two ways to solve this problem

  • Address to the service provider
  • Configure the service registry, register the service provider to the registry, and then the service consumer points to the registry to obtain the service address from the registry

The modification method is as follows: modify dubbo:reference in application.xml in the service consumer.

 <dubbo:reference id="loginService" interface="com.gupaoedu.demo.ILoginService"
     url="dubbo://192.168.1.104:20880/com.gupaoedu.demo.ILoginService"/>

summary

To briefly summarize the whole process above, it is not difficult to find that Dubbo middleware provides us with a solution for service remote communication. Through Dubbo framework, developers can quickly and efficiently build remote communication implementation under microservice architecture.

I wonder if you find that when we use dubbo to publish services or consume services, we use Spring configuration to complete the whole process. The advantage is that when we learn or use dubbo, if you have used the Spring framework, the difficulty of learning it will be greatly reduced. We can also see that dubbo is fully integrated with Spring. Therefore, when we analyze the source code of dubbo, we will still have some Spring related content.

Moreover, if you have studied my handwritten RPC class before, you can basically guess its entire implementation structure. You may as well boldly guess some implementation details of dubbo, so as to help you better understand dubbo in the follow-up in-depth study.

Import registry

Dubbo is not only an RPC framework, but also a service governance framework. It provides functions such as unified management of services and service routing.

In the above case, we just covered up Dubbo as a point-to-point service for RPC communication, but just as we learned the content of spring cloud earlier, how to manage, maintain and dynamically discover more services?

Moreover, as can be seen from Dubbo's architecture diagram, Dubbo naturally supports service registration and discovery. The earliest officially recommended service registration center is zookeeper. Of course, there are many registration centers that Dubbo can support, such as

Consumer, etcd, nacos, sofa, zookeeper, eureka, redis, etc. obviously, Dubbo is developing into an independent micro service solution.

Integrate Zookeeper as a service registry

  • Add the jar package dependency of zookeeper

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>2.7.8</version>
    </dependency>
  • Modify the configuration of service providers and service consumers

    <dubbo:registry address="zookeeper://192.168.216.128:2181" />

Integrate Nacos as a service registry

  • Start nacos

    docker run --name nacos -d -p 8848:8848 --privileged=true --restart=always -e JVM_XMS=512m -e JVM_XMX=2048m -e MODE=standalone -e PREFER_HOST_MODE=hostname -v /home/nacos/logs:/home/nacos/logs nacos/nacos-server
    • privileged: with this parameter, the root in the container has real root permission. Otherwise, the root in the container is only an external ordinary user permission.
    • When Docker restarts, the container restarts automatically
    • PREFER_HOST_MODE: ip # if the host name is supported, you can use hostname. Otherwise, you can use ip. The default is ip
  • Add dependency

    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>1.2.1</version>
    </dependency>
  • Modify configuration

    <dubbo:registry address="nacos://192.168.216.128:8848" timeout="10000" />

Dubbo Spring Cloud

Since we are talking about Spring Cloud Alibaba, it is necessary for us to understand how Dubbo integrates Spring Cloud for use.

Dubbo Spring Cloud is built on the native Spring Cloud and covers the native features of Spring Cloud. Compared with the native governance of Spring Cloud, Dubbo Spring Cloud provides a more stable and mature implementation.

The specific characteristics are as follows:

Why Dubbo Spring Cloud instead of Spring Cloud Dubbo? In my opinion, Dubbo itself is a self-contained ecosystem, and its service governance and maturity are more prominent than Spring cloud.

Therefore, in fact, Dubbo's integration of spring cloud is the standard system of Dubbo's mature ecology to embrace spring cloud.

Dubbo Spring Cloud is developed based on Dubbo Spring Boot 2.7.1[1] and Spring Cloud 2.x. no matter whether the developer is a Dubbo user or a Spring Cloud user, it can easily control and migrate applications upward at a cost close to "zero"

Starting from 2.7.0, the version of Dubbo Spring Boot is consistent with that of Dubbo

Next, we can use the Dubbo Spring Cloud to make a simple case implementation

Create a project

  • Create a maven project of spring cloud Dubbo example
  • Add three modules respectively

    • spring-cloud-dubbo-sample-api
    • spring-cloud-dubbo-sample-provider
    • spring-cloud-dubbo-sample-consumer

The latter two modules are applications of spring boot.

Modify the spring cloud Dubbo sample provider module.

  • Move the dependencies of the dependency management section to parent pom.xml
  • Modify pom.xml in spring cloud Dubbo sample provider to increase the dependency of parent module

    <parent>
        <groupId>com.gupaoedu.dubbo</groupId>
        <artifactId>spring-cloud-dubbo-example</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
  • Add maven dependency

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-dubbo</artifactId>
    </dependency>
    <dependency>
        <groupId>com.gupaoedu.dubbo</groupId>
        <version>1.0-SNAPSHOT</version>
        <artifactId>spring-cloud-dubbo-sample-api</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

Define service interface

In the spring boot Dubbo sample API module, define the interface

public interface IHelloService {

    String sayHello();
}

Implementation services

Implement IHelloService interface in spring boot Dubbo sample provider

public class HelloServiceImpl implements IHelloService{

    @Override
    public String sayHello() {
        return "Hello GuPao";
    }
}

Add @ EnableDiscoveryClient annotation

@EnableDiscoveryClient
@SpringBootApplication
public class SpringCloudDubboSampleProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudDubboSampleProviderApplication.class, args);
    }

}

Configure dubbo service publishing

  • Add the @ Service annotation to the Service implementation class

    @Service
    public class HelloServiceImpl implements IHelloService{
    
        @Override
        public String sayHello() {
            return "Hello GuPao";
        }
    }
  • Configure dubbo provider information

    # dubbo service scan basic package path
    dubbo.scan.base-packages=com.gupaoedu.dubbo.springclouddubbosampleprovider
    
    dubbo.protocol.id=dubbo
    # The protocol configuration exposed by the Dubbo service, in which the sub attribute name is the protocol name and port is the protocol port (- 1 indicates the auto increment port, starting from 20880)
    dubbo.protocol.name=dubbo
    dubbo.protocol.port=-1
    
    spring.cloud.nacos.discovery.server-addr=192.168.216.128:8848
    • dubbo.scan.base-packages: Specifies the scanning benchmark package of the Dubbo service implementation class
    • Dubbo.protocol: the protocol configuration exposed by the Dubbo service, in which the sub attribute name is the protocol name and port is the protocol port (- 1 indicates the self increment port, starting from 20880)
    • Dubbo. Registry: Dubbo service registry configuration, where the value of the sub attribute address is "spring"- cloud://localhost ", which indicates that you can mount to the Spring Cloud registry
    • Spring.cloud.nacos.discovery: Nacos service discovery and registration configuration, where the sub attribute server addr specifies the Nacos server host and port

Version specification

The version number format of the project is in the form of x.x.x, where the value type of X is a number, which starts from 0 and is not limited to the range of 0 ~ 9. When the project is in the incubator stage, the first version number is fixed to 0, that is, the version number is in the format of 0.x.x.

Since the interfaces and annotations of Spring Boot 1 and Spring Boot 2 in the Actuator module have changed greatly, and there are also major changes in the upgrade of spring cloud commons from version 1.x.x to version 2.0.0, we adopt the version consistent with the version number of spring boot:

  • Version 1.5.x is applicable to Spring Boot 1.5.x
  • Version 2.0.x is applicable to Spring Boot 2.0.x
  • Version 2.1.x is applicable to Spring Boot 2.1.x
  • Version 2.2.x is applicable to Spring Boot 2.2.x

Building service consumers

  • Add jar package dependency

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-dubbo</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>com.gupaoedu.dubbo</groupId>
        <version>1.0-SNAPSHOT</version>
        <artifactId>spring-cloud-dubbo-sample-api</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  • Add profile

    spring.application.name=spring-cloud-dubbo-sample-consumer
    dubbo.application.name=spring-cloud-dubbo-sample-consumer
    
    dubbo.cloud.subscribed-services=spring-cloud-dubbo-sample-provider
    spring.cloud.nacos.discovery.server-addr=192.168.216.128:8848

    In addition to the difference in the application name spring.application.name, spring cloud Dubbo client sample adds the setting of the attribute dubbo.cloud.subscribed-services. And this value applies "spring cloud Dubbo sample provider" to the service provider.

    Its main function is that the service consumer subscribes to the list of application names of the service provider. If it needs to subscribe to multiple applications, it is divided by ",". The default value of "*" is not recommended. It will subscribe to all apps.

  • Write test code

    @RestController
    @EnableDiscoveryClient
    @SpringBootApplication
    public class SpringCloudDubboSampleConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudDubboSampleConsumerApplication.class, args);
        }
        @Reference
        IHelloService helloService;
    
        @GetMapping("/say")
        public String say(){
            return helloService.sayHello();
        }
    
    }

    #Multi registry support

Compared with spring cloud, dubbo is powerful in providing functional support for many different scenarios, such as multi registry support.

The so-called multiple registries means that dubbo can configure the addresses of multiple registries at the same time, and then register to different registries for different types of services.

Dubbo multi registry can support several scenarios

Deploy a service to multiple registries

spring cloud based configuration

  • Add jar package dependency

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>2.7.8</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
            <exclusion>
                <artifactId>log4j</artifactId>
                <groupId>log4j</groupId>
            </exclusion>
        </exclusions>
    </dependency>
  • Modify application configuration

    dubbo.registries.registry1.address=nacos://192.168.216.128:8848
    dubbo.registries.registry1.timeout=10000
    dubbo.registries.registry2.address=zookeeper://192.168.216.128:2181
    dubbo.registries.registry2.timeout=10000
    
    #spring.cloud.nacos.discovery.server-addr=192.168.216.128:8848
    spring.cloud.nacos.discovery.register-enabled=false
    spring.cloud.nacos.discovery.watch.enabled=false
    spring.cloud.service-registry.auto-registration.enabled=false
    • spring.cloud.service-registry.auto-registration.enabled turn off the automatic registration of spring cloud
    • spring.cloud.nacos.discovery.watch.enabled/spring.cloud.nacos.discovery.register-enabled turn off the service registration and listening of Nacos

    The purpose of this is to avoid the service registration and discovery mechanism of spring cloud and follow dubbo's own service registration and discovery mechanism

  • Modify service configuration

    @Service(registry = {"registry1","registry2"})
    public class HelloServiceImpl implements IHelloService{
    
        @Override
        public String sayHello() {
            return "Hello GuPao";
        }
    }

References to multiple registries

  • Modify the application.properties of the consumer

    dubbo.registries.registry1.address=nacos://192.168.216.128:8848
    dubbo.registries.registry1.timeout=10000
    dubbo.registries.registry2.address=zookeeper://192.168.216.128:2181
    dubbo.registries.registry2.timeout=10000
    
    spring.cloud.nacos.discovery.register-enabled=false
    spring.cloud.nacos.discovery.watch.enabled=false
    spring.cloud.service-registry.auto-registration.enabled=false
  • Add jar package dependency

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>2.7.8</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
            <exclusion>
                <artifactId>log4j</artifactId>
                <groupId>log4j</groupId>
            </exclusion>
        </exclusions>
    </dependency>

Dubbo integration based on spring boot

In fact, in the use of dubbo spring cloud, it is not very friendly to configure multiple service registries, and there are some potential problems. After all, dubbo and spring cloud are completely different ecological coupling, which will inevitably lead to some compatibility problems. For example, the multi registry support we just configured needs to turn off the support for automatic service registration and discovery of spring cloud itself. In essence, we choose one of the two ecosystems as the main way to use it.

Therefore, in the spring cloud ecosystem, you can minimize the use of dubbo's flexibility and embrace the standard ecosystem of spring cloud. Of course, if you want to use dubbo as an independent ecosystem, you can use spring boot+Dubbo for integration,

Here is also a quick build for you.

In addition, dubbo's integration into spring boot has another advantage, that is, it can inherit the characteristics of spring boot itself

  • Automatic assembly (annotation driven, automatic assembly)
  • Production ready (security mechanism, health detection, externalized configuration)

Create project structure

Create basic project structure

  • spring-boot-dubbo-example [maven]

    • spring-boot-dubbo-sample-api [maven]
    • spring-boot-dubbo-sample-provider [spring boot]
    • spring-boot-dubbo-sample-consumerp [spring-boot]

Add jar package dependency

Starting from 2.7, the version of dubbo is consistent with the version of dubbo spring boot, so you don't have to worry about the version.

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.7</version>
</dependency>
<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>1.2.1</version>
</dependency>

Add services and publish

@DubboService
public class SayHelloServiceImpl implements ISayHelloService{
    @Override
    public String sayHello() {
        return "Hello GuPaoEdu.com";
    }
}
spring.application.name=spring-boot-dubbo-sample-provider

dubbo.registry.address=nacos://192.168.216.128:8848
dubbo.scan.base-packages=com.gupaoedu.springboot.dubbo.springbootdubbosampleprovider.service

dubbo.protocol.name=dubbo
dubbo.protocol.port=-1

Write service reference code

  • Add jar package dependency

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.gupaoedu.com</groupId>
        <version>1.0-SNAPSHOT</version>
        <artifactId>spring-boot-dubbo-sample-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>1.2.1</version>
    </dependency>
  • Add web test class

    @DubboReference
    ISayHelloService sayHelloService;
    
    @GetMapping("/get")
    public String get(){
        return sayHelloService.sayHello();
    }
    dubbo.registry.address=nacos://192.168.216.128:8848

Different services are registered to different registries

It can be found from the above configuration that we can configure different registries for different services, which will not waste time demonstrating.

Cluster of multiple registries

If a service consumer references multiple registries, the first thing a service consumer should do at this time is to balance the load of the registry, get a target registry, and then get the address list of service providers from the target registry, and then access the cluster. The implementation principle is shown in the figure below

Of course, there are three ways to specify the load balancing configuration of the registry

  • Specify priority

    <!-- come from preferred="true" The address of the registration center will be selected preferentially, only when there is no address available for the center Fallback Go to another registry -->
    <dubbo:registry address="zookeeper://${zookeeper.address1}" preferred="true" />
  • Same as zone priority

    <!-- When selecting the site, it will be different from that in the flow zone key For matching, the traffic will be distributed to the same priority zone Address of -->
    <dubbo:registry address="zookeeper://${zookeeper.address1}" zone="beijing" />
  • Weight polling

    <!-- The addresses from Beijing and Shanghai clusters will be 10:1 To distribute traffic -->
    <dubbo:registry id="beijing" address="zookeeper://${zookeeper.address1}" weight="100" />
    <dubbo:registry id="shanghai" address="zookeeper://${zookeeper.address2}" weight="10" />

Interface multi version support

Usually, when we develop an interface, we may face an interface modification, but at this time, because some online projects are using this interface, if we modify it directly, it may have a great impact on online services.

Therefore, dubbo provides support for interface versions in this case.

Specific configuration mode

  • The server provides different versions of implementations for the same interface
  • And configure the version declaration in the dubboservice annotation

    @DubboService(registry = {"registry1","registry2"},version = "1.0")
  • The service consumer specifies the consumption version number

    @DubboReference(registry = {"registry1","registry2"},version = "2.0")
    ISayHelloService sayHelloService;

Multi protocol support

When the company originally adopted other rpc frameworks, if it wants to migrate to Dubbo, the multi protocol support provided by Dubbo can provide almost zero cost migration.

For a service, you can publish multiple interfaces of different protocols at the same time, or you can publish different protocol types for different interfaces. Since 2.7, dubbo has supported some mainstream protocols. At present, the supported protocols are

dubbo protocol, hessian protocol, http protocol, thrift, rmi, webservice, grpc, rest, etc. In addition to the first time, dubbo also provides a very flexible scalability mechanism. Companies that have customization needs or are currently using protocols that dubbo does not support can expand by themselves.

The overall flexibility and pluggability are more powerful than spring cloud.

JAX-RS protocol description

REST (expressive resource transfer) support in Dubbo is implemented based on jax-rs 2.0 (Java API for restful web services).

REST is an architectural style. In short, it is a constraint on the api interface. It locates resources based on the URL and uses http verbs (GET/POST/DELETE) to describe operations

REST has been proposed for a long time. In the early days, developers would use various tools to implement REST. For example, Servlets are often used to develop RESTful programs. As REST is adopted by more and more developers, JCP(Java community process) proposes JAX-RS specification and provides a new annotation based way to develop RESTful services. With such a specification, developers do not need to care about the communication layer, but only about resources and data objects.

The implementation of JAX-RS specification includes Apache CXF, Jersey (reference implementation of JAX-RS provided by Sun), RESTEasy(jboss Implementation), etc.

The REST implemented in Dubbo is based on the RESTEasy framework provided by Jboss

We often use the RESTful implementation in spring MVC, which is also an implementation of JAX-RS specification

Add REST support

  • Add jar package dependency

    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>3.13.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>3.13.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>9.4.19.v20190610</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>9.4.19.v20190610</version>
    </dependency>
  • Modify profile

    dubbo.protocols.dubbo.name=dubbo
    dubbo.protocols.dubbo.port=-1
    
    dubbo.protocols.rest.name=rest
    dubbo.protocols.rest.port=8888
    dubbo.protocols.rest.server=jetty
  • Modify the interface definition of api

    @Path("/")
    public interface ISayHelloService {
    
        @GET
        @Path("say")
        String sayHello();
    
    }

Copyright notice: unless otherwise stated, all articles on this blog adopt CC BY-NC-SA 4.0 license agreement. Reprint please indicate from Mic to take you to learn architecture!
If this article is helpful to you, please pay attention and praise. Your persistence is the driving force of my continuous creation. Welcome to WeChat public official account for more dry cargo.

Posted by ChrisML123 on Mon, 06 Dec 2021 23:07:49 -0800