风在路上 风在路上
首页
导航站
  • Java-Se

    • Java基础
  • Java-Se进阶-多线程

    • 多线程
  • Java-Se进阶-java8新特性

    • java8新特性
  • Java-ee

    • JavaWeb
  • Java虚拟机

    • JVM
  • golang基础

    • golang基础
  • golang框架

    • gin
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • Redis
    • ElasticSearch
    • MongoDB
  • ORM

    • MyBatis
    • MyBatis-Plus
  • Spring

    • Spring
  • SpringMVC

    • SpringMVC1
    • SpringMVC2
  • SpringCloud

    • SpringCloud
  • 中间件

    • RabbitMQ
    • Dubbo
  • 秒杀项目
  • Git
  • Linux
  • Docker
  • JWT
  • 面试
  • 刷题
开发问题😈
设计模式
关于💕
归档🕛
GitHub (opens new window)

风

摸鱼
首页
导航站
  • Java-Se

    • Java基础
  • Java-Se进阶-多线程

    • 多线程
  • Java-Se进阶-java8新特性

    • java8新特性
  • Java-ee

    • JavaWeb
  • Java虚拟机

    • JVM
  • golang基础

    • golang基础
  • golang框架

    • gin
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • Redis
    • ElasticSearch
    • MongoDB
  • ORM

    • MyBatis
    • MyBatis-Plus
  • Spring

    • Spring
  • SpringMVC

    • SpringMVC1
    • SpringMVC2
  • SpringCloud

    • SpringCloud
  • 中间件

    • RabbitMQ
    • Dubbo
  • 秒杀项目
  • Git
  • Linux
  • Docker
  • JWT
  • 面试
  • 刷题
开发问题😈
设计模式
关于💕
归档🕛
GitHub (opens new window)
  • mybatis

  • mybatis-plus

  • Spring

  • SpringMvc

  • RabbitMQ

  • Dubbo

    • Dubbo知识体系
    • Dubbo
      • 必要的安装
        • 1、安装Zookeeper
        • 2、安装maven
        • 3、安装运行Dubbo-admin
      • demo
        • 创建工程(三个模块)
        • 父工程
        • 一个provider
        • 一个consumer
        • 一个api-common
      • 一些配置
        • 方法调用超时时间
        • 重试次数
        • 多版本
        • 使用JavaConfig方式配置Dubbo服务
      • 高可用
        • 1、zookeeper宕机与dubbo直联
        • 2、集群下dubbo负载均衡配置
        • 1.Random LoadBalance(随机)
        • 2.RoundRobin LoadBalance(轮询)
        • 测试
        • 3.LeastActive LoadBalance
        • 4.ConsistentHash LoadBalance
        • 3、服务降级
        • 4、集群容错
        • 集群容错模式
        • 5、整合hystrix
    • 服务注册(provider服务暴露)
    • 服务发现(consumer服务引入)
    • 服务调用过程
    • SPI机制
    • 负载均衡机制
    • 服务容错、降级
    • Dubbo的服务异常处理
  • SpringCloud

  • 框架
  • Dubbo
zdk
2022-05-28
目录

Dubbo

Table of Contents generated with DocToc (opens new window)

  • 必要的安装
    • 1、安装Zookeeper
    • 2、安装maven
    • 3、安装运行Dubbo-admin
  • demo
    • 创建工程(三个模块)
      • 父工程
      • 一个provider
      • 一个consumer
      • 一个api-common
  • 一些配置
    • 方法调用超时时间
    • 重试次数
    • 多版本
    • 使用JavaConfig方式配置Dubbo服务
  • 高可用
    • 1、zookeeper宕机与dubbo直联
    • 2、集群下dubbo负载均衡配置
      • 1.Random LoadBalance(随机)
      • 2.RoundRobin LoadBalance(轮询)
        • 测试
      • 3.LeastActive LoadBalance
      • 4.ConsistentHash LoadBalance
    • 3、服务降级
    • 4、集群容错
      • 集群容错模式
    • 5、整合hystrix

# 必要的安装

# 1、安装Zookeeper

  1. 腾讯微云安装包下载链接 (opens new window)

  2. 上传到Linux,使用下面的命令压解

    tar -xzvf xxx
    
    1
  3. 进入到压解目录的conf目录下,添加配置文件zoo.cfg

    # The number of milliseconds of each tick
    tickTime=2000
    # The number of ticks that the initial 
    # synchronization phase can take
    initLimit=10
    # The number of ticks that can pass between 
    # sending a request and getting an acknowledgement
    syncLimit=5
    # the directory where the snapshot is stored.
    # do not use /tmp for storage, /tmp here is just 
    # example sakes.
    dataDir=/usr/local/src/zookeeper/data
    # the port at which the clients will connect
    clientPort=2181
    # the maximum number of client connections.
    # increase this if you need to handle more clients
    #maxClientCnxns=60
    #
    # Be sure to read the maintenance section of the 
    # administrator guide before turning on autopurge.
    #
    # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
    #
    # The number of snapshots to retain in dataDir
    #autopurge.snapRetainCount=3
    # Purge task interval in hours
    # Set to "0" to disable auto purge feature
    #autopurge.purgeInterval=1
    
    ## Metrics Providers
    #
    # https://prometheus.io Metrics Exporter
    #metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
    #metricsProvider.httpPort=7000
    #metricsProvider.exportJvmInfo=true
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
  4. 进入/bin目录,启动server

    bash zkServer.sh start #启动
    
    bash zkServer.sh status #查看状态
    
    bash zkServer.sh stop #停止
    
    1
    2
    3
    4
    5
  5. 可以通过zkCli连接server

    bash zkCli.sh -server localhost:2181
    #连接成功之后,通过键入help命令,查看客户端所支持的所有命令。(只要输入任何zkCli不能识别的内容,都会出现所有命令)
    
    1
    2

# 2、安装maven

--进入opt安装目录
[root@hadoop1 /]# cd opt/

--解压maven安装包
[root@hadoop1 opt]# tar -zxvf apache-maven-3.8.5-bin.tar.gz

--将文件移动到/usr/local/maven目录下,注:linux安装软件大多都安装在usr/local目录下
[root@hadoop1 opt]# mv apache-maven-3.8.5 /usr/local/maven

--配置maven系统环境变量文件,注:添加在末尾即可
[root@hadoop1 /]# vim /etc/profile
# maven config
export M2_HOME=/usr/local/maven
export PATH=$PATH:$M2_HOME/bin

--刷新环境变量: 使用source /etc/profile编译后只能在当前终端生效
[root@hadoop1 /]# source /etc/profile

--验证maven是否安装成功,注:返回版本信息表示maven安装成功
[root@hadoop1 /]# mvn -version
Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0)
Maven home: /usr/local/maven
Java version: 1.8.0_161, vendor: Oracle Corporation, runtime: /usr/java/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "2.6.32-642.el6.x86_64", arch: "amd64", family: "unix"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

配一下镜像

<mirrors>
	<!--阿里云公共仓库是central仓和jcenter仓的聚合仓-->
    <mirror>
		<id>aliyunmaven</id>
		<mirrorOf>*</mirrorOf>
		<name>阿里云公共仓库</name>
		<url>https://maven.aliyun.com/repository/public</url>
	</mirror>
	<mirror>
		<id>aliyunmaven</id>
		<mirrorOf>*</mirrorOf>
		<name>阿里云谷歌仓库</name>
		<url>https://maven.aliyun.com/repository/google</url>
	</mirror>
	<mirror>
		<id>aliyunmaven</id>
		<mirrorOf>*</mirrorOf>
		<name>阿里云阿帕奇仓库</name>
		<url>https://maven.aliyun.com/repository/apache-snapshots</url>
	</mirror>
	<mirror>
		<id>aliyunmaven</id>
		<mirrorOf>*</mirrorOf>
		<name>阿里云spring仓库</name>
		<url>https://maven.aliyun.com/repository/spring</url>
	</mirror>
	<mirror>
		<id>aliyunmaven</id>
		<mirrorOf>*</mirrorOf>
		<name>阿里云spring插件仓库</name>
		<url>https://maven.aliyun.com/repository/spring-plugin</url>
	</mirror>
	<mirror>
		<id>maven</id>
		<mirrorOf>*</mirrorOf>
		<name>maven仓库</name>
		<url>https://mvnrepository.com/</url>
	</mirror>
</mirrors>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 3、安装运行Dubbo-admin

下载这个jar包 运行即可

腾讯微云 (opens new window)

# demo

# 创建工程(三个模块)

# 父工程

pom:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.zdk</groupId>
    <artifactId>dubbo-study</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>boot-user-service-provider</module>
        <module>boot-user-service-consumer</module>
        <module>api-commons</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.0.RELEASE</version>
            </dependency>
            <!--zookeeper客户端-->
            <dependency>
                <groupId>com.github.sgroschupf</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.1</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.zookeeper</groupId>
                        <artifactId>zookeeper</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--dubbo自定义启动器-->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.7.8</version>
            </dependency>
            <!--curator提供zookeeper连接-->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.12.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>2.12.0</version>
            </dependency>

        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

# 一个provider

pom:

<?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-study</artifactId>
        <groupId>com.zdk</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>boot-user-service-provider</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.zdk</groupId>
            <artifactId>api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--zookeeper客户端-->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--dubbo自定义启动器-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!--curator提供zookeeper连接-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
        </dependency>

    </dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

# 一个consumer

pom:

<?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-study</artifactId>
        <groupId>com.zdk</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>boot-user-service-consumer</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.zdk</groupId>
            <artifactId>api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>


        <!--zookeeper客户端-->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--dubbo自定义启动器-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!--curator提供zookeeper连接-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
        </dependency>
    </dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

# 一个api-common

不需要依赖,就存储共用的bean或者interface等

步骤

  1. 将服务提供者注册到注册中心(zookeeper)

    spring:
      application:
        name: userServiceProvider
    dubbo:
      application:
        name: userServiceProvider
      scan:
        base-packages: com.zdk.service
      registry:
        address: zookeeper://211.69.238.105:2181
        client: curator
        timeout: 10000
      config-center:
        timeout: 10000
    server:
      port: 8991
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    然后将接口暴露出来

    @Service//这个是spring的注解
    @DubboService//这个注解将接口暴露
    public class UserServiceImpl implements UserService {
        @Override
        public List<UserAddress> userList() {
            List<UserAddress> users = new ArrayList<>();
            users.add(new UserAddress(1, "zdk1", "123", "张迪凯1","asdsad","sadsad"));
            users.add(new UserAddress(2, "zdk2", "123", "张迪凯2","asdsad","sadsad"));
            return users;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  2. 让服务消费者去注册中心定于服务提供者的服务地址

    spring:
      application:
        name: userServiceConsumer
    dubbo:
      application:
        name: userServiceConsumer
      registry:
        address: zookeeper://211.69.238.105:2181
    server:
      port: 8992
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    然后在需要UserService的地方对它进行引用

    @Service
    public class OrderServiceImpl implements OrderService {
        @DubboReference//此注解就是引用provider暴露的接口实现
        private UserService userService;
    
        @Override
        public List<UserAddress> initOrder(String userID) {
            //查询用户的收货地址
            return userService.userList();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  3. 测试结果

    @RestController
    public class OrderController {
    
        @Autowired
        private OrderService orderService;
    
        @GetMapping("/initOrder")
        public List<UserAddress> initOrder(@RequestParam("uid") String userId){
            return orderService.initOrder(userId);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    image-20220529134944664

# 一些配置

# 方法调用超时时间

服务提供者可以使用暴露服务的注解中的参数methods,然后使用@Method注解来指定该指定的方法的调用超时时间,超时即报错

@DubboService(methods = {@Method(name = "userList",timeout = 2000)})
public class UserServiceImpl implements UserService {
    @Override
    public List<UserAddress> userList() {
		//xxx
    }
}
1
2
3
4
5
6
7

同样,消费者也可指定,同时指定时,以消费者优先

@DubboReference(methods = {@Method(name = "userList", timeout = 2000)})
private UserService userService;
1
2

总的配置原则

  1. 精确优先(方法级优先,接口次之,全局配置再次之)
  2. 消费者设置优先(如果级别一样,则消费方优先,提供方次之)

# 重试次数

服务调用失败后的重试次数,消费者设置如下(服务提供者类似)

@DubboReference(methods = {
            @Method(name = "userList", 
                    timeout = 2000,
                    retries = 2
            )
    })
1
2
3
4
5
6

配置后发起了两次重试

image-20220529142942212

一般只在幂等的方法上设置重试次数,非幂等性的方法不重试

# 多版本

我们可以提供对同一个服务的不同实现版本

//指定原实现类版本为1.0.0
@Service
@DubboService(methods = {@Method(name = "userList",timeout = 2000)},version = "1.0.0")
public class UserServiceImpl implements UserService {//xxx}
1
2
3
4

新增一个实现类,指定版本为1.0.1

@Service
@DubboService(methods = {@Method(name = "userList",timeout = 2000)},version = "1.0.1")
public class UserServiceImpl2 implements UserService {
    @Override
    public List<UserAddress> userList() {
        System.out.println("进入服务接口版本2..");
        List<UserAddress> users = new ArrayList<>();
        users.add(new UserAddress(1, "zdk1", "123", "张迪凯1","asdsad","sadsad"));
        users.add(new UserAddress(2, "zdk2", "123", "张迪凯2","asdsad","sadsad"));
//        try {
//            TimeUnit.SECONDS.sleep(3);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
        return users;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

在消费者引用时,指定引用的版本

@Service
public class OrderServiceImpl implements OrderService {
    @DubboReference(methods = {
            @Method(name = "userList",
                    timeout = 2000,
                    retries = 2
            )
    },check = false,version = "1.0.1")//指定使用1.0.1版本
    private UserService userService;

    @Override
    public List<UserAddress> initOrder(String userID) {
        //查询用户的收货地址
        return userService.userList();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

测试结果:

image-20220529144447044

# 使用JavaConfig方式配置Dubbo服务

在provider项目中添加如下配置类

package com.zdk.config;

import com.zdk.service.OrderService;
import com.zdk.service.UserService;
import org.apache.dubbo.config.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zdk
 * @date 2022/5/29 15:13
 */
@Configuration
public class DubboConfig {

    /**
     * 注入应用配置
     * @param registryConfig 注册中心
     * @return
     */
    @Bean
    public ApplicationConfig applicationConfig(RegistryConfig registryConfig){
        //配置服务的名字
        ApplicationConfig applicationConfig = new ApplicationConfig("userServiceProvider");
        //配置注册中心
        applicationConfig.setRegistry(registryConfig);
        return applicationConfig;
    }

    /**
     * 注册一个 注册中心配置的Bean
     * @return
     */
    @Bean
    public RegistryConfig registryConfig(){
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setPort(2181);
        registryConfig.setAddress("211.69.238.105");
        registryConfig.setProtocol("zookeeper");
        return registryConfig;
    }

    /**
     * 配置通信协议 比如协议使用dubbo协议 20880端口
     * @return
     */
    @Bean
    public ProtocolConfig protocolConfig(){
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20880);
        return protocolConfig;
    }

    /**
     * 配置提供的服务
     * @param userService
     * @return
     */
    @Bean
    public ServiceConfig<UserService> serviceConfigBase(@Qualifier("userServiceImpl") UserService userService){
        ServiceConfig<UserService> serviceConfig = new ServiceConfig<>();
        //配置服务接口
        serviceConfig.setInterface(UserService.class);
        //配置和这个接口的实现
        serviceConfig.setRef(userService);
        //配置接口的版本
        serviceConfig.setVersion("1.0.0");

        //配置每个方法的信息
        MethodConfig methodConfig = new MethodConfig();
        methodConfig.setName("userList");
        methodConfig.setTimeout(2000);

        //将方法关联到ServiceConfig中
        List<MethodConfig> methodConfigList = new ArrayList<>();
        serviceConfig.setMethods(methodConfigList);

        //还可以配置ProviderConfig、MonitorConfig等等

        return serviceConfig;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

配置了这些以后yaml里面的除了server:port之外后可以注释掉,测试效果一样。注意上面注册的版本,我注册的1.0.1,然后consumer调用1.0.0,是调用不到的,出现no aviable provider错误

# 高可用

# 1、zookeeper宕机与dubbo直联

现象:zookeeper注册中心宕机,还可以消费dubbo暴露的服务

原因

健壮性

  • 监控中心宕掉不影响使用,只是丢失部分采样数据
  • 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  • 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
  • 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  • 服务提供者无状态,任意一台宕掉后,不影响使用
  • 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
高可用:通过设计,减少系统不能提供服务的时间;

通过 @DubboReference(url = "127.0.0.1:20880")方式可以使用dubbo直联

# 2、集群下dubbo负载均衡配置

在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random,即随机调用。

# 1.Random LoadBalance(随机)

随机,按权重设置随机概率。

在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

# 2.RoundRobin LoadBalance(轮询)

轮循,按公约后的权重设置轮循比率。

存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

# 测试

以Tomcat端口8991、8992、8993,dubbo服务端口20881、20882、20883启动三个provider,并配置消费者的

@DubboReference注解的loadbalance值为:RoundRobinLoadBalance.NAME

image-20220602164526758

各自的service输出对应的 System.out.println("进入服务接口..xxx");

然后启动消费者进行访问测试,连续访问三次,可以看到,依次访问了provider1、2、3

image-20220602164613994

# 3.LeastActive LoadBalance

最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。简单来说就是响应速度越快的提供者会收到更多的请求,反之亦然

使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

# 4.ConsistentHash LoadBalance

一致性 Hash,相同参数的请求总是发到同一提供者。

当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。算法参见:http://en.wikipedia.org/wiki/Consistent_hashing

缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key="hash.arguments" value="0,1" />

缺省用 160 份虚拟节点,如果要修改,请配置 <dubbo:parameter key="hash.nodes" value="320" />

# 3、服务降级

什么是服务降级?

当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。

可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。

向注册中心写入动态配置覆盖规则:

RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));
1
2
3

其中:

  • mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
  • 还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。

当然,最直接的修改方式可以直接在dubbo-admin中将某个要降级的服务"屏蔽"(屏蔽消费者),此屏蔽为mock=force:return+null,强制返回null模式

image-20220602165820148

而如果选择容错,则是mock=fail:return+null模式,消费者调用失败以后,才会返回null

# 4、集群容错

在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试

# 集群容错模式

Failover Cluster

失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。

重试次数配置如下:

<dubbo:service retries="2" />

或

<dubbo:reference retries="2" />

或

dubbo:reference

<dubbo:method name="findFoo" retries="2" />

</dubbo:reference>

Failfast Cluster

快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

Failsafe Cluster

失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

Failback Cluster

失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

Forking Cluster

并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。

Broadcast Cluster

广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。

集群模式配置

按照以下示例在服务提供方和消费方配置集群模式

<dubbo:service cluster="failsafe" />

或

<dubbo:reference cluster="failsafe" />

# 5、整合hystrix

Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能

先在父pom里面加上springcloud的版本依赖

            <!--spring-cloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
1
2
3
4
5
6
7
8

然后在provider中加入hystrix的依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
1
2
3
4

然后在Application类上增加@EnableHystrix注解来启用hystrix

同样,在消费者中也进行对应的操作

接下来在provider端对暴露服务的方法进行处理:

@Service
@DubboService(methods = {@Method(name = "userList",timeout = 2000)},version = "1.0.0")
public class UserServiceImpl implements UserService {
    //使用此注解的fallbackMethod 指定服务调用失败后的回调方法
    @HystrixCommand(fallbackMethod = "hello")
    @Override
    public List<UserAddress> userList() {
        System.out.println("进入服务接口..3333");
        List<UserAddress> users = new ArrayList<>();
        users.add(new UserAddress(1, "zdk1", "123", "张迪凯1","asdsad","sadsad"));
        users.add(new UserAddress(2, "zdk2", "123", "张迪凯2","asdsad","sadsad"));
//        try {
//            TimeUnit.SECONDS.sleep(3);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
        if (Math.random()>0.5){
            throw new RuntimeException();
        }
        return users;
    }
	//回调方法
    public List<UserAddress> hello() {
        System.out.println("服务调用失败啦.......");
        List<UserAddress> users = new ArrayList<>();
        users.add(new UserAddress(1, "error", "error", "error","error","error"));
        return users;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

多次调用以后,出现错误时,发现调用了回调的hello方法

image-20220602180050139

在 GitHub 上编辑此页 (opens new window)
#Dubbo
最后更新: 2022/10/04, 16:10:00
Dubbo知识体系
服务注册(provider服务暴露)

← Dubbo知识体系 服务注册(provider服务暴露)→

Theme by Vdoing | Copyright © 2022-2025 zdk | notes
湘ICP备2022001117号-1
川公网安备 51142102511562号
本网站由 提供CDN加速/云存储服务
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式