Microservice architecture | 12.1 remote communication using Apache Dubbo

Posted by tom2oo8 on Thu, 20 Jan 2022 23:26:13 +0100

preface

reference material:
<Spring Microservices in Action>
Principles and practice of Spring Cloud Alibaba microservice
"Spring cloud framework development tutorial in Silicon Valley of station B" Zhou Yang

Apache Dubbo is a distributed service framework, which mainly realizes high-performance and transparent calls between multiple systems;
Dubbo related content the author wrote an introductory note before: Dubbo quick start notes - environment and configuration . The introductory notes emphasize some basic features of Dubbo to integrate with Zookeeper. Therefore, we will focus on the connection, difference and integration between Dubbo and Spring Cloud;

1. Dubbo Basics

1.1 what is Dubbo

  • Apache Dubbo is a distributed service framework, which mainly realizes high-performance and transparent calls between multiple systems;
  • In short, it is an RPC framework, but different from the ordinary RPC framework, it provides service governance functions, such as service registration, monitoring, routing, fault tolerance, etc;

1.2 architecture diagram of Dubbo

1.3 differences between spring cloud and Dubbo

Comparison itemDubboSpring Cloud
communication protocolBased on TCP protocol transmission, Netty is used to cooperate with Hession serialization to complete RPC communicationCommunication of calling remote procedure based on HTTP protocol + REST interface
Service invocation modeRPCREST API
locationThe product of SOA EraMicroservice architecture Era
FocusReuse of services and solving the problem of information island; Service governanceDecoupling to reduce the coupling between services; Microservice governance package
modularService registration center, service provider, service consumer and control centerDistributed one-stop framework
  • HTTP requests will have larger packets and occupy more bandwidth. However, REST is more flexible than RPC. The dependence of service providers and callers only depends on a contract, and there is no strong dependence at the code level, which is more appropriate in the microservice environment emphasizing rapid evolution;
  • The specific comparison of module components is as follows:
assemblyDubboSpring Cloud (Netflix)
Registration CenterIt used to be Zookeeper, but now it promotes NacosSpring Cloud Eureka
Service monitoringDubbo-monitorSpring Boot Admin
Fuse6 fault tolerance modesSpring Cloud Hystrix
load balancing Four load balancing strategiesSpring Cloud Ribbon
service degradation Mock mechanismThe @ HystrixCommand annotation for Hystrix
gatewaynothingSpring Cloud Zuul
to configurenothingSpring Cloud Config
Service trackingnothingSpring Cloud Sleuth
data streamnothingSpring Cloud Stream
Batch tasknothingSpring Cloud Task
Message busnothingSpring Cloud Bus

1.4 characteristics of Dubbo

  • It supports service publishing of multiple protocols. The default is dubbo: / /. It can also support rest: / /, webservice: / /, thrift: / /, etc;
  • Support a variety of different registration centers, such as Nacos, ZooKeeper and Redis, and will also support Consul, Eureka, Etcd, etc. in the future;
  • Support a variety of serialization technologies, such as avro, fst, fastjson, hessian2, kryo, etc;
  • It has perfect functions in service governance, such as cluster fault tolerance, service routing, load balancing, service degradation, service flow limitation, service monitoring, security verification, etc;
  • Chinese documents;

1.5 Dubbo's six fault-tolerant modes

Fault tolerant modeMode nameexplainApplicable scenario
Failover Cluster[default] fail to switch automaticallyWhen the service call fails, it will switch to other machines in the cluster for retry. The default number of retries is 2. The number of retries can be modified through the attribute retries=2It is usually used for read operation (query), because transactional operation will cause data duplication
Failfast ClusterRapid failureWhen the service call fails, an error is reported immediately, that is, only one call is initiatedIt is usually used for some idempotent write operations (addition, deletion and modification), such as adding data; To avoid the problem of repeated data insertion in the case of uncertain results
Failsafe ClusterFail safeWhen an exception occurs, the exception is ignored directlyUse Failover Cluster(retries = "0") to handle (add, delete, modify) operations
Failback ClusterAutomatic reply after failureWhen an exception occurs in the service call, record the failed request in the background and resend it regularlyIt is suitable for message notification operation to ensure that the request will be sent successfully
Forking ClusterParallel submissionCall multiple services in the cluster in parallel, and return as long as one of them succeeds. You can set the maximum number of parallels by forks=2
Broadcast ClusterBroadcast notificationBroadcast calls all service providers. If any service reports an error, it means that the service call failsIt is usually used to notify all service providers to update cache or local resource information
  • The fault-tolerant mode can be extended by itself;

  • The configuration is also very simple. Just add a cluster parameter in the @ Service interface;

    @Service(cluster = "failfast") //Change the fault tolerance mode to fast failure
    public class TestServiceImpl implements TestService {
    	@Override
    	public String test() {
    	    ...
    	}
    }
    

1.6 Dubbo's four load balancing strategies

Load balancing strategyPolicy nameexplain
Random LoadBalanceRandom algorithmYou can set a larger weight value for servers with better performance. The larger the weight value, the greater the probability of randomness
RoundRobin LoadBalancepolling Set the polling proportion according to the weight after the Convention
LeastActive LoadBalanceLeast active callSlower nodes will receive fewer requests
ConsistentHash LoadBalanceConsistency HashRequests with the same parameters are always sent to the same service provider
  • The load balancing policy can be extended based on the SPI mechanism in Dubbo;

  • The configuration is also very simple. Just add a loadbalance parameter in the @ Service interface;

    @Service(loadbalance = "roundrobin") //Change the load balancing policy to polling
    public class TestServiceImpl implements TestService {
    	@Override
    	public String test() {
    	    ...
    	}
    }
    

1.7 host binding rules

  • Host binding refers to the IP address published by Dubbo service. By default, Dubbo will find and bind the host IP address in the following order:
    • Find Dubbo in environment variable_ IP_ TO_ The IP address configured by the bind attribute;
    • Find Dubbo protocol. The IP address configured by the host attribute is empty by default. If it is not configured or the IP address is illegal, continue to look down;
    • Via localhost Gethostaddress obtains the local IP address. If the acquisition fails, continue to look down;
    • If the address of the registry is configured, use Socket communication to connect to the address of the registry, and use the for loop through Socket getLocalAddress(). Gethostaddress() scans each network card to obtain the IP address of the network card;
  • The IP address obtained is not the address written to the registry. By default, the IP address written to the registry takes precedence over Dubbo in the environment variable_ IP_ TO_ The registry property the configured IP address. If this attribute is not configured, the previously obtained IP address will be selected and written to the registry;
  • Problem: using the default host binding rules, the P address obtained may be incorrect;
    • Reason: Dubbo's strategy to detect the local IP address is to call localhost first Gethostaddress. The principle of this method is to map the IP address by obtaining the host name of the local machine. If it points to a wrong IP address, the wrong address will be registered on the ZooKeeper node as the address published by the service;
    • Solution:
      • Configure the correct IP address mapping corresponding to the machine name in / etc/hosts;
      • Add Dubbo to the environment variable_ IP_ TO_ Bind or DUBBO_IP_TO_REGISTRY property, Value is the bound host address;
      • Through Dubbo Protocolhost sets the host address;

2. Build Dubbo service provider

2.1 building service interface module

  • Dubbo officially recommends that the service interface be marked as a Jar package and released to the warehouse;

  • In this way, the service consumer can rely on the Jar package to complete remote communication through interface call. For service providers, they also need to rely on the Jar package to complete the implementation of the interface;

  • The method is as follows:

  • Create a new spring cloud Dubbo sample API module and add POM XML dependency file;

    <!-- Dubbo -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>${dubbo.version}</version>
    </dependency>
    
  • Create a new interface under the service package:

    public interface TestService {
    	String test(String message);
    }
    
  • Execute the mvn install command to install the interface jar package to the local warehouse;

2.2 add POM XML dependency file

<!-- Spring Cloud Core package-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter</artifactId>
</dependency>

<!-- Dubbo Spring Cloud Starter -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>

<!-- Sample API Interface declaration-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-dubbo-sample-api</artifactId>
</dependency>

<!-- Spring Cloud Nacos Service Discovery -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>

2.3 modify application YML profile

spring:
  application:
    name: spring-cloud-dubbo-provider
  cloud:
    zookeeper:
      discovery:
        register: true  #Indicates that the service is to be registered in the registry
      connect-string: localhost:2181  #zookeeper server location
dubbo:     
  protocol:
    name: dubbo
    port: 20880

2.4 add comments on the main program class

  • @DubboComponentScan: scan all annotations under the package where the main program class is located and its sub packages, and register the class under @ Servicr annotation into the container;

2.5 implement the interface defined in 2.1

@Service
public class TestServiceImpl implements TestService {
    @Value("${dubbo.application.name}")
    private String serviceName;
    
	@Override
	public String test(String message) {
		return serviceName;
	}
}
  • You can add two attributes in the @ Service annotation to configure cluster and loadbalance, which are used to configure fault-tolerant mode and load balancing policy respectively;
  • For details, see "6 fault tolerance modes of 1.5 Dubbo" and "4 load balancing strategies of 1.6 Dubbo" in this chapter

3. Build Dubbo service consumers

3.1 add POM XML dependency file

  • With the service provider;
<!-- Spring Cloud Core package-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter</artifactId>
</dependency>

<!-- Dubbo Spring Cloud Starter -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>

<!-- Sample API Interface declaration-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-dubbo-sample-api</artifactId>
</dependency>

<!-- Spring Cloud Nacos Service Discovery -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>

3.2 modify application YML profile

spring:
  application:
    name: spring-cloud-dubbo-consumer
  cloud:
    zookeeper:
      discovery:
        register: false #Indicates that the service should not be registered in the registry
      connect-string: localhost:2181  
dubbo:     
  cloud:
    subscribed-services: spring-cloud-dubbo-provider  #Represents the application name list of the service provider subscribed by the service caller. The default value is "*", which is not recommended

3.3 modify business class

  • Use the @ Reference annotation in the service class to inject TestService;
@RestController
public class TestController{
    @Reference 
    private TestService testService;
    
    @GetMapping("/message")
    public String testController(){
        return testService.test("message");
}

4. Use Mock configuration on the consumer side to realize service degradation

  • In this example, the service degradation policy will be configured for the TestService interface defined in 2.1;
  • The configuration of degradation strategy is based on service consumers;

4.1 implement a service degradation method for the interface

public class MockTestService implements TestService {
	@Override
	public String test(String message) {
		return "Currently inaccessible";
	}
}

4.2 add mock parameter to @ Reference annotation

@RestController
public class TestController{
    @Reference(mock = "com.dlhjw.springcloud.mock.MockTestService", cluster="failfast")
    private TestService testService;
    
    @GetMapping("/message")
    public String testController(){
        return testService.test("message");
}
  • Modify the @ Reference annotation in the TestController class and add the mock parameter;
  • The attribute cluster="failfast" is set, because the default fault tolerance policy will initiate two retries, and the waiting time is long;

5. Dubbo uses Zookeeper as the registration center (Spring Boot)

5.1 download Zookeeper server

5.2 introduction of POM XML dependency file

  • Service providers and service consumers need to introduce the same dependencies;
<!-- Zookeeper Correlation dependency -->
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.5.3-beta</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.0.1</version>
</dependency>

<!-- Dubbo Correlation dependency -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.5</version>
</dependency>

<!-- Spring Boot rely on -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

5.3 service providers

5.3.1 modify application YML profile

spring:
  application:
    name: springboot-dubbo-demo 
dubbo:
  #Service provider information
  application:
    name: springboot-provider      
  protocol:
    name: dubbo
    port: 20880
  registry:
    address: zookeeper://Localhost: 2181 #zookeeper address
  #scan:
    #base-packages: com.dlhjw.dubbo.service.impl  #Specify the scanning benchmark package of Dubbo service implementation class, which is equivalent to @ DubboComponentScan on the main program class

5.3.2 add notes on the main program class

  • @DubboComponentScan: the function is the same as @ ComponentScan of Spring Boot, but the @ Service annotation provided by Dubbo should be scanned here;
  • @DubboComponentScan(basePackages = "com.dlhjw.dubbo.service.impl")
  • If the above application has been configured, there is no need to add it here;

5.3.3 write business class

  • Create an interface and its implementation class:
public interface TestService {
    void testDubbo();
}
@Service(version = "1.0.0",timeout = 3000)
public class TestServiceImpl implements TestService{
    @Override
    public void testDubbo() {
    }
}
  • Note: @ Service annotation is com alibaba. dubbo. config. annotation. Under Service package;

5.4 service consumers

5.4.1 modify application YML profile

dubbo:
  #Information of service consumers
  application:
    name: springboot-consumer 
  registry:
    #zookeeper address
    address: zookeeper://localhost:2181

5.4.2 add notes on the main program class

5.4.3 writing business classes

  • Here, you can directly call the TestService provided by the service provider in the controller interface;
@Reference(version = "1.0.0",timeout = 300)
private TestService testService;
  • @The Reference annotation can obtain a remote proxy object;

6. Dubbo uses Nacos as the registry (Spring Boot)

  • Only the automatic configuration of Spring Boot is used here;
  • Only examples of service providers are provided here, which are similar to service consumers;

6.1 download Nacos server

6.2 engineering structure

  • Create a new parent project spring cloud Nacos sample, which contains two modules: Nacos sample API and Nacos sample provider;
  • Declare the interface in the Nacos sample API;
public interface IHelloService{
    String sayHello(String name);
}

6.3 introduction of POM XML dependency file

  • Add dependent files in Nacos sample provider:
<!-- Interface definition class -->
<dependency>
  <groupId>com.gupaoedu.book.nacos</groupId>
  <version>1.0-SNAPSHOT</version>
  <artifactId>nacos-sample-api</artifactId>
</dependency>
<!-- Nacos of starter assembly -->
<dependency>
  <groupId>com.alibaba.boot</groupId>
  <artifactId>nacos-discovery-spring-boot-starter</artifactId>
  <version>0.2.4</version>
  <exclusions>
    <exclusion>
      <groupId>com.alibaba.spring</groupId>
      <artifactId>spring-context-support</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<!-- Dubbo of starter assembly -->
<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo-spring-boot-starter</artifactId>
  <version>2.7.5</version>
</dependency>

6.4 modify application YML profile

dubbo:
  application:
    name: spring-boot-dubbo-nacos-sample 
  registry:
    address: nacos://127.0.0.1:8848 # based on Nacos protocol
  protocol: 
    name: dubbo
    port: 20880

6.5 add comments on the main program class

  • @DubboComponentScan: the package scanning annotation of dubbo;

6.6 write business class

  • Implement the interface defined in 6.2;
@Service 
public class HelloServiceImpl implements IHelloService{
    @Override 
    public String sayHello(String name){
        return "He1lo World:"+name;
    }
}        

6.7 start up test

  • Start the service, access the Nacos console, enter "service management" - > "service list", and you can see all services registered on Nacos;

7. Dubbo uses Nacos as the registry (Spring Cloud)

  • Only examples of service providers are provided here, similar to service consumers;

7.1 download Nacos server

7.2 engineering structure

  • Create a new parent project, spring cloud Nacos sample, which contains two modules: spring cloud Nacos sample API and spring cloud Nacos sample provider;
  • Declare the interface in the Nacos sample API;
public interface IHelloService{
    String sayHello(String name);
}

7.3 add POM XML dependency

  • Display the specified version of the declaration dependency in the parent project;
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-dependencies</artifactId>
  <version>Greenwich.SR2</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.1.11.RELEASE</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  <version>2.1.1.RELEASE</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>
  • Add dependent files in spring cloud Nacos sample provider:
<!-- Spring Cloud Core package -->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-context</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<!-- Spring Cloud of Dubbo rely on -->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>

<!-- api modular -->
<dependency>
  <groupId>com.gupaoedu.book.springcloud</groupId>
  <artifactId>spring-cloud-dubbo-sample-api</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

<!-- be based on Nacos Service registration and discovery -->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-context</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-context</artifactId>
  <version>2.1.1.RELEASE</version>
</dependency>

7.4 add application YML dependency file

  • The main difference between this integration method and Spring Boot is POM XML configuration file and application YML dependent files;
spring: 
  application: 
    name: spring-cloud-nacos-sample 
  cloud: 
    nacos: 
      discovery:
        server-addr: 127.0.0.1:8848  #Nacos service registry address

dubbo: 
  scan: 
    base-packages: com.gupaoedu.book.nacos.bootstrap  #The function is equivalent to @ DubboComponentScan   
  protocol: 
    name: dubbo
    port: 20880
  registry:
    address: spring-cloud://localhost # mounts the service to the Spring Cloud registry

7.5 no additional comments are required on the main program class

7.6 writing business

  • Implement the interface defined in 7.2;
@Service 
public class HelloServiceImpl implements IHelloService{
    @Override 
    public String sayHello(String name){
        return "He1lo World:"+name;
    }
}        

last

Newcomer production, if there are mistakes, welcome to point out, thank you very much! Welcome to the official account and share some more everyday things. If you need to reprint, please mark the source!

Topics: Dubbo Distribution Spring Cloud rpc Microservices