The use of Dubbo, just read this article

Dubbo

1. Overview of Dubbo

  1. Dubbo is a Java RPC framework for providing high-performance remote service invocation solutions and SOA service governance solutions

In simple terms, Dubbo is used to provide consumers with a calling interface (register the interface in the registry)

  1. Dubbo operation flowchart

Insert picture description here

Node role description:

● Provider: the service provider that exposes the service
● Consumer: the service consumer who calls the remote service
● Container: the service running container
● Registry: the registry for service registration and discovery
● Monitor: the monitoring center that counts the number of service calls and the call time

  1. Text explanation of Dubbo running process

(1) Start the container, load and run the service provider
(2) When the provider starts, register the service it provides in the registry
(3) When the consumer starts, subscribe to the service it needs in the registry
(4) The registry is used for The URL provided by the management provider; ZooKeeper is the registration center recommended by Dubbo
(5) The monitoring center manages the entire process

  1. Consider failures or changes

(1) The registry returns the provider address list to the consumer. If there is a change, the registry pushes the changed data to the consumer.
(2) The consumer selects a provider from the provider address list to call. If the call fails, Choose another
(3) The consumer and the provider record the number of calls and call time in the memory, and send statistics to the monitoring center every minute

Two, Dubbo running example

Create two modules, one as the provider and the other as the consumer. The consumer can remotely call the service provided by the service through Dubbo, and start the two parties separately for testing

Note: Both parties are required to be independently runnable war projects, not relying on maven to call the provider's service

Insert picture description here

  1. Development of interfaces that both parties need to use

Reasons for using the interface as an independent module:

(1) The provider needs to implement this interface to define a specific method (service), so it needs to define this interface
(2) The consumer needs to define this interface to call the methods in the interface (using the service provided by this interface)

This leads to duplication of the definition of this interface between the two parties. Once the interface is changed, the modification of the two parties is cumbersome, so the public interface is regarded as an independent module

package com.itheima.service;

public interface UserService {
    
    

    public String sayHello();
}
//并且需要将此模块install成为jar包


Insert picture description here

  1. Provider development

(1) The content in the pom.xml file

<groupId>com.itheima</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!-- war项目 -->

<!-- jar包版本控制 -->
<properties>
    <spring.version>5.1.9.RELEASE</spring.version>
    <dubbo.version>2.7.4.1</dubbo.version>
    <zookeeper.version>4.0.0</zookeeper.version>
</properties>

<dependencies>

    <!--Dubbo服务所需jar包-->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>${dubbo.version}</version>
    </dependency>

    <!--ZooKeeper服务所需jar包-->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>${zookeeper.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>${zookeeper.version}</version>
    </dependency>

    <!--依赖公共的接口模块-->
    <dependency>
        <groupId>com.itheima</groupId>
        <artifactId>dubbo-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <!--以及其余必须的如spring、springmvc、Log4J等jar包-->
    <!--以及tomcat服务器的插件-->
</dependencies>

Insert picture description here

(2) Content in web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
<!-- 监听Spring配置文件 -->
    <param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

(3) Content in UserServiceImpl

//导入公共接口所在类的包
/**
 * 1. @Service注解是Dubbo包下的,并不是Spring包下的
 * 2. 使用了此注解的类提供的方法将会对外发布,并将访问地址,端口等注册到注册中心中
 */
@Service
public class UserServiceImpl implements UserService {
    
    
    @Override
    public String sayHello() {
    
    
        return "hello Dubbo !";
    }
}

(4) Content in applicationContext.xml

<!--Dubbo的配置-->

<!-- 1. 配置项目的名称(自定义),用于注册中心计算项目之间依赖关系,唯一 -->
<dubbo:application name="dubbo-service"/>

<!-- 2. 配置注册中心的地址,用于连接注册中心,address为Zookeeper所在Linux的ip地址及ZooKeeper端口号 -->
<dubbo:registry address="zookeeper://192.168.200.130:2181"/>

<!-- 3. 配置Dubbo的包扫描,使用了Dubbo包下的@Service注解的类会被发布为服务 -->
<dubbo:annotation package="com.itheima.service.impl" />

  1. Consumer development

(1) Content in pom.xml

<groupId>com.itheima</groupId>
<artifactId>dubbo-web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!-- war项目 -->

<!-- jar包版本控制 -->
<properties>
    <spring.version>5.1.9.RELEASE</spring.version>
    <dubbo.version>2.7.4.1</dubbo.version>
    <zookeeper.version>4.0.0</zookeeper.version>
</properties>

<dependencies>

    <!--Dubbo服务所需jar包-->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>${dubbo.version}</version>
    </dependency>

    <!--ZooKeeper服务所需jar包-->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>${zookeeper.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>${zookeeper.version}</version>
    </dependency>

    <!--依赖公共的接口模块-->
    <dependency>
        <groupId>com.itheima</groupId>
        <artifactId>dubbo-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

	<!-- web模块并没有直接依赖service模块,通过远程调用方式 -->

    <!--以及其余必须的如spring、springmvc、Log4J等jar包-->
    <!--以及tomcat服务器的插件-->
</dependencies>


Insert picture description here

(2) Content in web.xml

<!-- Springmvc -->   
   <servlet>
       <servlet-name>springmvc</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:spring/springmvc.xml</param-value>
       </init-param>
   </servlet>
   <servlet-mapping>
       <servlet-name>springmvc</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>

(3) Content in UserController

//导入公共接口所在类的包
@RestController
@RequestMapping("/user")
public class UserController {
    
    
    /**
     * 1. @Reference注解导入的为Dubbo包
     * 2. @Reference注解作用:
     *    (1) 从zookeeper注册中心获取提供方的访问url
     *    (2) 进行远程调用RPC
     *    (3) 将结果封装为一个代理对象,赋值给userService对象
    */
    @Reference
    private UserService userService;

    @RequestMapping("/sayHello")
    public String sayHello(){
    
    
        return userService.sayHello();
    }
}

(4) The content in springmvc.xml

<mvc:annotation-driven/>
<!-- 扫描使用了Controller注解的类 -->
<context:component-scan base-package="com.itheima.controller"/>

<!--dubbo的配置-->
<!-- 1.配置项目的名称,唯一 -->
<dubbo:application name="dubbo-web" >
    <!-- 在同一台机器上同时部署提供方和消费方需要区分二者,否则二者同时使用默认端口22222,冲突 -->
    <!-- 实际开发中,提供方与消费方通常部署在不同的机器上,无需关心此项-->
    <dubbo:parameter key="qos.port" value="33333"/>
</dubbo:application>
<!-- 2. 配置注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.200.130:2181"/>
<!-- 3. 配置dubbo包扫描,扫描使用了Dubbo包下的@Reference注解 -->
<dubbo:annotation package="com.itheima.controller" />

  1. operation result

(1) Run this command on the service module and web module separately, as the two war projects of the provider and the consumer

Insert picture description here

(2) The log information after the web module runs is as follows

Insert picture description here

(3) The operation effect is as follows

Insert picture description here

Three, serialization

When the provider (producer) and consumer (consumer) need to pass the Pojo type, the Pojo class needs to implement the Serializable interface under the IO package and become a binary stream for transmission

Four, address cache

  1. Question: After the registration center hangs up, can the service be accessed normally?

  2. Answer: Yes; because the consumer will cache the producer's address locally when calling the service for the first time, and will not pass through the registry when accessing this address later; when the producer's address changes, the registry will notify The mechanism notifies consumers of the new address;
    Note: After the registration center is hung up, existing consumers can access the service, but new consumers will not be able to access the service

Five, timeout

  1. When the consumer calls the producer’s service, if there is a blocking, waiting, etc., the consumer will wait forever

  2. At a certain peak moment, if a large number of requests are blocked, it will cause an avalanche phenomenon

  3. Dubbo uses a timeout mechanism to solve this problem. Set a timeout period. If the service cannot be accessed within this time, it will automatically disconnect and report a timeout error.

  4. Use the timeout attribute to configure the timeout period, the default value is 1000, in milliseconds

//timeout属性设置超时时间,单位毫秒;
@Service(timeout = 3000)
  1. Consumer @Referenceannotations can also use the timeout attribute, but it is generally recommended to use it in the producer, because defining the service in the producer can estimate the required time and facilitate the timeout setting

Six, try again

  1. A timeout period is set. If the service call cannot be completed within this time, the connection will be automatically disconnected and an error will be reported

  2. If there is a network jitter (the network is unstable and temporarily interrupted but quickly recovered), the request will fail

  3. Dubbo uses a retry mechanism to avoid such problems

  4. Set the number of retries through the retries attribute, the default is two (plus the first request, a total of three)

//retries属性设置重传次数
@Service(timeout = 3000, retries = 3)

Seven, multiple versions

  1. When a new version of the producer’s service appears, all consumers will not be allowed to access this version, but some consumers will be asked to call this version first, and after confirming that there is no problem, all consumers will call this version, which is called gray Degree release

  2. Dubbo uses the version attribute to set and call different versions of the same interface

Producer code:

@Service(version = "v1.0", timeout = 3000)
public class UserServiceImpl1 implements UserService {
    
    ...}

@Service(version = "v2.0")
public class UserServiceImpl2 implements UserService {
    
    ...}

Consumer code:

@Reference(version = "v2.0")
private UserService userService;
//成功调用v2.0版本的服务

Eight, load balancing

  1. Consumers need to use load balancing strategies to access the producer cluster. There are four types:

(1) Random: Default strategy; set random probability by weight, the higher the weight, the easier it is to be accessed
(2) RoundRobin: Polling by request
(3) LeastActive: the shorter the response time, the easier it is to be accessed
(4) ConsistentHash: The same request always calls the same service

Note: The four strategies are similar to Nginx's load balancing strategy

  1. Producer configuration, set the weight through the weight attribute, the default value is 100
@Service(weight = 200)
  1. Consumer configuration, set the policy through the loadbalance attribute, the default value is random
@Reference(loadbalance = "random")
@Reference(loadbalance = "roundrobin")
@Reference(loadbalance = "leastactive")
@Reference(loadbalance = "consistenthash")
  1. Note: To start multiple services on the same machine, you need to modify the following two ports, each service cannot be the same to prevent conflicts

Insert picture description here

Nine, cluster fault tolerance

  1. The cluster fault tolerance modes are as follows:

(1) Failover Cluster: Default mode; failure retry, default retry twice, use retries configuration; when failure occurs, report an error, and retry other servers twice, generally used for read operations, write operations may cause writes due to delays, etc. Incoming data duplication

(2) Failfast Cluster: Fast failure; initiate a call, if it fails, an error will be reported immediately without retrying, usually used for write operations

(3) Failsafe Cluster: Failsafe Cluster: When an exception occurs, no error is reported, just ignored, and an empty result is returned

(4) Failback Cluster: automatic recovery from failure; after the request fails, the background records the failed request and resends it regularly

(5) Forking Cluster: Call multiple services in parallel, and return as long as one succeeds

(6) Broadcast Cluster: Broadcast calls to all providers, call them one by one, and report an error if any call fails

  1. Consumer configuration, use the cluster attribute to set the cluster fault tolerance mode, the default value is failover
@Reference(cluster = "failover")

X. Service degradation

  1. When the server pressure is high, some services are released according to the actual situation, and only the core services are reserved to ensure the overall efficient operation of the service

  2. There are two ways to downgrade the service

(1) mock = force:return null: means that all calls made by consumers to the service return a null value, which is equivalent to shielding the service

(2) mock = fail:return null: indicates that the consumer's call to the service fails (will retry), and then returns a null value without reporting an error

  1. Consumer configuration, use the mock attribute to set the service degradation method
@Reference(mock = "force : return null")

Guess you like

Origin blog.csdn.net/weixin_49343190/article/details/112982259