Dubbo RPC communication of Spring Cloud series

Posted by bitt3n on Wed, 17 Jun 2020 04:52:16 +0200

About Dubbo

  

  

Official website: http://dubbo.apache.org/zh-cn/

  Github: https://github.com/apache/dubbo

On February 15, 2018, dubbo, Alibaba's service governance framework, successfully became an Apache foundation incubation project.

Apache Dubbo is a high-performance and lightweight open source Java RPC framework, which provides three core capabilities: interface oriented remote method call, intelligent fault tolerance and load balancing, and automatic service registration and discovery.

  

Dubbo architecture

  

Dubbo provides three core functions: interface based remote call, fault tolerance and load balancing, and automatic registration and discovery of services. Dubbo framework is widely used in Alibaba, as well as Dangdang, qunar, Netease koala, Didi, etc.

Node role description

  

node Role description
Provider Exposed service provider
Consumer Service consumer calling remote service
Registry Service registration and discovery registry
Monitor Monitoring Center for statistics of service call times and call times
Container Service running container

  

Call relationship description

  

  1. The service container is responsible for starting, loading, and running the service provider.
  2. When the service provider starts, it registers its services with the registry.
  3. At startup, service consumers subscribe to the registry for services they need.
  4. The registration center returns the service provider address list to the consumer. If there is any change, the registration center will push the change data to the consumer based on the long connection.
  5. Service consumer, from the provider address list, based on the soft load balancing algorithm, selects one provider to call, and selects another to call if the call fails.
  6. Service consumers and providers accumulate the number and time of calls in memory, and regularly send statistical data to the monitoring center every minute.

  

Dubbo quick start

  

Let's understand the use of Dubbo through a simple case, and then integrate Dubbo based on Spring Boot and Spring Cloud environment.

Dubbo adopts the all Spring configuration mode, transparently accessing the application, without any API intrusion to the application, just use Spring to load the configuration of Dubbo.

  

rely on

  

Above JDK 1.6 and Maven 3.0, we use Maven multi module aggregation project to build api module, provider module and consumer module.

  

Polymerization Engineering

  

The structure of the project is shown in the figure below, which is a brief introduction:

  • Dubbo API: Service Interface
  • Dubbo provider: depending on service interface, specific business implementation, service provider
  • Dubbo coonsumer: dependent service interface, remote call service, service consumer

  

Dependency

  

Dubbo parent's pom.xml Depends on apache dubbo.

<dependencies>
    <!-- apache dubbo rely on -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.7</version>
    </dependency>
</dependencies>

  

Dubbo provider and Dubbo consumer's pom.xml Rely on Dubbo API service interface.

<dependencies>
    <!-- dubbo-api rely on -->
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>dubbo-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

  

Define service interface

  

Written in Dubbo API HelloService.java

package org.example.service;

/**
 * Hello service
 */
public interface HelloService {

    String sayHello(String name);

}

  

Define service provider

  

Implementing service interface in provider module

  

Written in Dubbo provider HelloServiceImpl.java

package org.example.service.impl;

import org.example.service.HelloService;

/**
 * Service implementation
 */
public class HelloServiceImpl implements HelloService {

    public String sayHello(String name) {
        return "hello " + name;
    }

}

  

Configure service provider

  

  dubbo-provider.xml

<?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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- Provider application information for dependency calculation -->
    <dubbo:application name="hello-world-app"/>

    <!-- use multicast Broadcast registry exposure service address -->
    <dubbo:registry address="multicast://224.5.6.7:1234"/>

    <!-- use dubbo Protocol exposes service on port 20880 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- Declare the service interface to be exposed -->
    <dubbo:service interface="org.example.service.HelloService" ref="helloService"/>

    <!-- And local bean Same implementation services -->
    <bean id="helloService" class="org.example.service.impl.HelloServiceImpl"/>

</beans>

  

Load Spring configuration startup service

  

package org.example;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Publishing services
 */
public class Provider {

    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:dubbo-provider.xml");
        context.start();
        System.out.println("Service registration succeeded!");
        System.in.read(); // press any key to exit
    }

}

  

Define service consumers

  

Referencing remote services through Spring configuration

  

  dubbo-consumer.xml

<?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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- The consumer application name is used to calculate the dependency. It is not a matching condition. It should not be the same as the provider -->
    <dubbo:application name="consumer-of-helloworld-app"  />

    <!-- use multicast Broadcast registry exposure discovery service address -->
    <dubbo:registry address="multicast://224.5.6.7:1234" />

    <!-- Generate remote service agent, which can be connected with local bean Same use helloService -->
    <dubbo:reference id="helloService" interface="org.example.service.HelloService" />

</beans>

  

Load the Spring configuration and call the remote service

  

package org.example;

import org.example.service.HelloService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Call remote service
 */
public class Consumer {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:dubbo-consumer.xml");
        context.start();
        HelloService helloService = (HelloService) context.getBean("helloService"); // Get remote service agent
        String result = helloService.sayHello("world"); // Execute remote method
        System.out.println(result); // Show call results
    }
}

  

Dubbo common labels

  

  • dubbo:application : application name
  • dubbo:registry : connection registry information (configure Registry)
  • dubbo:protocol : protocol adopted by service provider to register service
  • dubbo:service : declare the service interface to be exposed
  • dubbo:reference : configure subscribed services (generate remote service proxy)

For more configuration information, please refer to: http://dubbo.apache.org/zh-cn/docs/user/references/xml/introduction.html

  

Registration Center

  

We have learned a lot from the registration center, such as ZooKeeper, Eureka, Consul, Nacos, etc. the registration center can manage system services more efficiently, such as service interface publishing, automatic rejection of invalid services, automatic recovery services, etc.

Dubbo supports five kinds of registration centers: Multicast, Nacos (recommended), zookeeper (recommended), Redis and Simple. This article focuses on the first two. For more information about the registration center, please refer to: http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html

  

Multicast registry

  

The Multicast registry does not need to start any central nodes, as long as the broadcast addresses are the same, they can discover each other.

  1. Provider broadcasts its address when it starts
  2. Broadcast subscription request when consumer starts
  3. When the provider receives the subscription request, unicast its address to the subscriber. If unicast=false is set, unicast is broadcast to the subscriber
  4. When the consumer receives the provider address, it connects to it for RPC calls.

Multicast is limited by network structure and is only suitable for small-scale application or development stage. Multicast address segment: 224.0.0.0 - 239.255.255.255

  

to configure

  

<dubbo:registry address="multicast://224.5.6.7:1234" />

Or

<dubbo:registry protocol="multicast" address="224.5.6.7:1234" />

  

In order to reduce the broadcast volume, Dubbo uses unicast to send the address information of the provider to the consumer by default. If multiple consumer processes are started on a machine at the same time, the consumer needs to declare unicast=false, otherwise only one consumer can receive the message.

When the server and the consumer are running on the same machine, the consumer also needs to declare unicast=false, otherwise the consumer cannot receive the message, resulting in No provider available for the service exception.

<dubbo:registry address="multicast://224.5.6.7:1234?unicast=false" />

Or

<dubbo:registry protocol="multicast" address="224.5.6.7:1234">
    <dubbo:parameter key="unicast" value="false" />
</dubbo:registry>

  

zookeeper registry

  

Zookeeper is a subproject of Apache Hadoop. It is a tree type directory service that supports change push. It is suitable for being a registry of Dubbo services. It has high industrial intensity and can be used in production environment. It is recommended.

  

Process Description:

  • When the service provider starts: to / dubbo/com.foo.BarService/providers Write your own URL address in the directory.
  • When service consumer starts: subscription / dubbo/com.foo.BarService/providers The provider URL address under the directory. And to / dubbo/com.foo.BarService/consumers Write your own URL address in the directory.
  • When monitoring center starts: Subscribe / dubbo/com.foo.BarService All provider and consumer URL addresses in the directory.

  

The following functions are supported:

  • When the provider is shut down abnormally, such as power failure, the registration center can automatically delete the provider information;
  • When the registration center is restarted, it can automatically recover the registration data and subscription request;
  • When the session expires, it can automatically recover the registration data and subscription request;
  • When setting< dubbo:registry check= "False" / > records the failed registration and subscription request, and the background regularly retries;
  • Available through< dubbo:registry username= "Admin" password = "1234" / > set zookeeper login information;
  • Available through< dubbo:registry group= "Dubbo" / > set the root node of zookeeper. If not configured, the default root node will be used;
  • Support * wildcard< dubbo:reference group= "*" version = "*" / > can subscribe to all groups and providers of all versions of the service.

As the old gold partner of Dubbo, ZooKeeper, we have shared how to use it when we explained Dubbo alone. This article is a series of Spring Cloud Alibaba articles, focusing on Nacos, so ZooKeeper is just a little more here.

  

Nacos registry

  

Nacos is an open source tool launched by Alibaba company, which is used to realize service discovery and configuration management of distributed system. Nacos is an important registry implementation in the Dubbo ecosystem.

Nacos website: https://nacos.io/zh-cn/

  Github: https://github.com/alibaba/nacos

  

Preparatory work

  

Before you integrate Nacos into your Dubbo project, make sure that the Nacos service is started in the background. For Nacos installation and other details, please refer to my previous article Alibaba Nacos registration center of Spring Cloud series (I),Alibaba Nacos registration center of Spring Cloud series (2).

  

Get started quickly

  

Dubbo's steps to integrate Nacos into a registry are very simple. The general steps can be divided into "increasing Maven dependency" and "configuring the registry".

  

rely on

  

The core dependencies are Dubbo registry Nacos and Nacos client.

<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-registry-nacos -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-registry-nacos</artifactId>
    <version>2.7.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client -->
<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>1.3.0</version>
</dependency>

  

Configure registry

  

Service providers and service consumers only need to adjust the address property configuration.

Stand alone configuration:

<!-- use Nacos Registry, stand-alone -->
<dubbo:registry address="nacos://127.0.0.1:8848"/>
<!-- or -->
<dubbo:registry protocol="nacos" address="127.0.0.1:2181"/>

Cluster configuration:

<!-- use Nacos Registry, clustered -->
<dubbo:registry address="nacos://192.168.10.101:2181?backup=192.168.10.102:2181,192.168.10.103:2181"/>
<!-- or -->
<dubbo:registry protocol="nacos" address="192.168.10.101:2181,192.168.10.102:2181,192.168.10.103:2181"/>

Then restart your Dubbo application, and the service provision and consumption information of Dubbo can be displayed in the Nacos console.

  

Spring Cloud Alibaba Nacos integrates Dubbo

  

In the previous article, whether we study Eureka, Consul or Nacos, the function of inter service communication is completed by Ribbon. Next, we use Dubbo to replace Ribbon.

  

Polymerization Engineering

  

Dubbo demo polymerization project. SpringBoot 2.3.0.RELEASE,Spring Cloud Hoxton.SR5 .

The structure of the project is shown in the figure below, which is a brief introduction:

  • Service API: Service Interface
  • Product service: commodity service, service provider, which provides the / product/list interface
  • Order service: order service, service consumer, remote call commodity service

  

Dependency

  

Dubbo demo's pom.xml .

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- Project coordinate address -->
    <groupId>com.example</groupId>
    <!-- Project module name -->
    <artifactId>dubbo-demo</artifactId>
    <packaging>pom</packaging>
    <!-- Project version name snapshot version SNAPSHOT,Official version RELEASE -->
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>service-api</module>
        <module>product-service</module>
        <module>order-service</module>
    </modules>

    <!-- inherit spring-boot-starter-parent rely on -->
    <!-- Use inheritance method to realize reuse, and all inheritable can be used -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
    </parent>

    <!--
        The dependent component version number is defined centrally, but is not imported,
        When a declared dependency is used in a subproject, the version number of the dependency can be omitted,
        In this way, the dependent versions used in the project can be managed uniformly
     -->
    <properties>
        <!-- Spring Cloud Hoxton.SR5 rely on -->
        <spring-cloud.version>Hoxton.SR5</spring-cloud.version>
        <!-- spring cloud alibaba rely on -->
        <spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>
    </properties>

    <!-- Project dependency management the parent project only declares dependency, and the child project needs to specify the required dependency(Version information can be omitted) -->
    <dependencyManagement>
        <dependencies>
            <!-- spring cloud rely on -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- spring cloud alibaba rely on -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

  

Service API pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-api</artifactId>

    <dependencies>
        <!-- lombok rely on -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

  

Product service depends on Nacos and Dubbo, as well as service API. The complete dependency is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!-- Inherit parent dependency -->
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product-service</artifactId>

    <!-- Project dependency -->
    <dependencies>
        <!-- spring cloud alibaba nacos discovery rely on -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- spring cloud alibaba dubbo rely on -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dubbo</artifactId>
        </dependency>
        <!-- spring boot web rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- service-api rely on -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>service-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!-- spring boot test rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

  

Order service depends on Nacos and Dubbo, as well as service API. The complete dependency is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!-- Inherit parent dependency -->
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order-service</artifactId>

    <!-- Project dependency -->
    <dependencies>
        <!-- spring cloud alibaba nacos discovery rely on -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- spring cloud alibaba dubbo rely on -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dubbo</artifactId>
        </dependency>
        <!-- spring boot web rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- service-api rely on -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>service-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!-- spring boot test rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

  

Define service interface

  

We define entity classes and service interface information in the service API module.

  

Entity class

  

  Product.java

package com.example.product.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {

    private Integer id;
    private String productName;
    private Integer productNum;
    private Double productPrice;

}

  Order.java

package com.example.product.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order implements Serializable {

    private Integer id;
    private String orderNo;
    private String orderAddress;
    private Double totalPrice;
    private List<Product> productList;

}

  

Service interface

  

package com.example.product.service;

import com.example.product.pojo.Product;

import java.util.List;

/**
 * Goods and services
 */
public interface ProductService {

    /**
     * Query product list
     *
     * @return
     */
    List<Product> selectProductList();

}

  

Define service provider

  

configuration file

  

The configuration file needs to configure Nacos registry and Dubbo related information. The core configuration is as follows:

server:
  port: 7070 # port

spring:
  application:
    name: product-service # apply name
  # Configure Nacos registry
  cloud:
    nacos:
      discovery:
        enabled: true # If you do not want to use Nacos for service registration and discovery, set it to false
        server-addr: 127.0.0.1:8848 # Nacos server address, stand-alone

# Dubbo
dubbo:
  # Provider application information for dependency calculation
  application:
    name: product-service
  # Using the nacos registry to expose service addresses
  registry:
    protocol: nacos
    address: spring-cloud://localhost
  # Using dubbo protocol to expose services on port 20880
  protocol:
    name: dubbo
    port: 20880
  # Scan services that need to be exposed, which can be replaced by @ EnableDubbo annotation
  #scan:
  #  base-packages: com.example.service

  

Service provider

  

Product service ProductServiceImpl.java

package com.example.service.impl;

import com.example.product.pojo.Product;
import com.example.product.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;

import java.util.Arrays;
import java.util.List;

/**
 * Goods and services
 * 		timeout Timeout for calling the service
 * 		version Is version number
 * 		group Group for
 * interface,group,version Three to determine a service
 */
@Slf4j
@Service(timeout = 5000, version = "1.0", group = "product-service")
public class ProductServiceImpl implements ProductService {

    /**
     * Query product list
     *
     * @return
     */
    @Override
    public List<Product> selectProductList() {
        log.info("Commodity service query commodity information...");
        return Arrays.asList(
                new Product(1, "Huawei Mobile", 1, 5800D),
                new Product(2, "Lenovo notebook", 1, 6888D),
                new Product(3, "Mi Pad ", 5, 2020D)
        );
    }

}

It is worth noting that the @ Service annotation is not a Spring annotation but a Dubbo annotation:

  

Startup class

  

The startup class scans the services to be exposed through the @ EnableDubbo annotation. If this option is configured in the configuration file, it can be omitted here.

package com.example;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Scan services that need to be exposed
@EnableDubbo(scanBasePackages = "com.example.service")
// Enable @ EnableDiscoveryClient annotation, which will be enabled by default in the current version
//@EnableDiscoveryClient
@SpringBootApplication
public class ProductServiceApplication {

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

}

  

Define service consumers

  

configuration file

  

The configuration file needs to configure Nacos registry and Dubbo related information. The core configuration is as follows:

server:
  port: 9090 # port

spring:
  application:
    name: order-service # apply name
  # Configure Nacos registry
  cloud:
    nacos:
      discovery:
        enabled: true # If you do not want to use Nacos for service registration and discovery, set it to false
        server-addr: 127.0.0.1:8848 # Nacos server address, stand-alone

# Dubbo
dubbo:
  # The consumer application name is used to calculate the dependency. It is not a matching condition. It should not be the same as the provider
  application:
    name: order-service
  # Discover services exposed by nacos registry
  registry:
    protocol: nacos
    address: spring-cloud://localhost
  cloud:
    subscribed-services: product-service # Subscription service, service name of remote call

  

Service consumers

  

Order service OrderServiceImpl.java

package com.example.service.impl;

import com.example.product.pojo.Order;
import com.example.product.service.ProductService;
import com.example.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    // dubbo provides @ Reference annotation, which can replace @ Autowired annotation to introduce remote services
    // If the version and grouping information are set when registering the service, the corresponding version and grouping information should also be set when calling the remote service
    @Reference(timeout = 5000, version = "1.0", group = "product-service")
    private ProductService productService;

    /**
     * Query order based on primary key
     *
     * @param id
     * @return
     */
    @Override
    public Order selectOrderById(Integer id) {
        log.info("Order service query order information...");
        return new Order(id, "order-001", "China", 22788D,
                productService.selectProductList());
    }

}

  

Startup class

  

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Enable @ EnableDiscoveryClient annotation, which will be enabled by default in the current version
//@EnableDiscoveryClient
@SpringBootApplication
public class OrderServiceApplication {

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

}

  

test

  

Start the Nacos server, then the service provider product service. Access: http://localhost:8848/nacos/ The console displays as follows:

  

Then start the service consumer, and the console displays as follows:

  

The order service calls the remote goods service, and the result is as follows:

  

Dubbo load balancing

  

In the cluster load balancing, Dubbo provides a variety of balancing strategies, which are random calls by default, and can also expand the load balancing strategy by itself.

  

Load balancing strategy

  

Random LoadBalance

  

  • Random, set the random probability according to the weight.
  • The probability of collision on a section is high, but the larger the adjustment amount is, the more uniform the distribution is.

RoundRobin LoadBalance

  

  • Polling: set the polling ratio according to the weight after the Convention.
  • There is a problem of slow providers accumulating requests. For example, the second machine is very slow, but it doesn't hang up. When the request is transferred to the second machine, it is stuck there. Over time, all requests are stuck in the second machine.

  

LeastActive LoadBalance

  

  • Minimum number of active calls, ping value (low latency) calls, random with the same latency.
  • Make slow providers receive fewer requests, because the slower providers have a greater difference in the count before and after the call.

ConsistentHash LoadBalance

  

  • Consistent Hash: requests with the same parameters are always sent to the same provider.
  • When a provider is hung, the request originally sent to the provider is spread to other providers based on the virtual node, which will not cause dramatic changes.
  • The algorithm is shown in: http://en.wikipedia.org/wiki/Consistent_hashing
  • Only the first parameter Hash is selected by default. If you want to modify it, please configure< dubbo:parameter key= " Hash.arguments " value="0,1" />
  • 160 virtual nodes are used by default. If you want to modify them, please configure< dubbo:parameter key= " hash.nodes " value="320" />

  

to configure

  

In general, the weight is not specified at the code level in the project, but the dynamic weight of the service is specified through the monitoring center (Dubbo admin). Official documents: http://dubbo.apache.org/zh-cn/docs/admin/introduction.html

  

xml

  

Server service level

<dubbo:service interface="..." loadbalance="roundrobin" weight="100" />

Client service level

<dubbo:reference interface="..." loadbalance="roundrobin" />

Server method level

<dubbo:service interface="..." weight="100">
    <dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>

Client method level

<dubbo:reference interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>

  

yaml

  

dubbo:
  provider:
    loadbalance: roundrobin
    weight: 100
  consumer:
    loadbalance: roundrobin

  

annotation

  

@Service(loadbalance = "roundrobin", weight = 100)
@Reference(loadbalance = "roundrobin")

At this point, all knowledge points of Dubbo RPC communication are finished.

This paper adopts < a href=“ http://creativecommons.org/licenses/by-nc-nd/4.0/ " target="_ Blank "> intellectual sharing" signature - non-commercial use - deduction prohibited 4.0 international "license agreement < / a >.

You can use < a href=“ https://mrhelloworld.com/categories " target="_ Blank "> categories < / a > see more about < a href =" https://mrhelloworld.com/categories/spring-cloud " target="_ Blank "> spring cloud < / a >.

  

🤗 Your comments and forwarding are my biggest support.

📢 Scan the code and follow Mr. halloward's "document + video". Each article is provided with a special video explanation, which makes learning easier~

Topics: Programming Dubbo Spring Apache Maven