Spring Cloud | 客户端 “负载均衡器“ : Ribbon


在这里插入图片描述

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材为:
《Spring Cloud微服务架构开发》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


  • 微服务架构中,负载均衡 是一个必不可少的技术负载均衡 决定着 整个服务集群性能稳定
  • Spring Cloud 体系中加入了 Netfix公司 ( 网飞公司 ) 的很多优秀产品,其中一个就是实现客户 负载均衡 工具 : Ribbon。下面将对 客户端负载均衡工具 : Ribbon 进行讲解

1. 什么是 “负载均衡” ? ( 通过 “负载均衡” 可以将 “用户请求” “分发” 到 不同的服务器,以此来提高 “性能” 和 “可靠性” )

  • 负载均衡“高可用” 网络基础架构 的一个关键组成部分有了负载均衡,我们通常 可以部署多台 “应用服务器”,然后
    通过负载均衡 将 “用户的请求” "分发"不同的服务器用来 提高网站应用数据库其他服务性能 以及 可靠性

    ---- 通过"负载均衡"可以 将用户的"请求" "分发"到 不同的服务器 ,以此来 提高"性能" 和 “可靠性”。

    ---- 通过 “负载均衡” 可以 部署多台 "服务器"。

  • 下面我们来看一个 不使用 “负载均衡”Web 架构如下图所示

    在这里插入图片描述

    上图中客户端之间通过因特网Web服务器端相连”。
    假想
    如果 Web 服务器 “宕机”
    用户访问网站时就将 “得不到” 任何响应,出现 单点故障问题 即使服务器可以正常工作如果 很多用户同时访问服务器数据 超过服务器的 处理能力,就会出现 响应速度慢 或者 无法连接 的情况,这也是用户无法接受的。

  • 引入负载均衡可以有效 解决上述问题,它可以将 负载 ( 工作任务 ) 进行 平衡分摊“多个” 执行单元 ( 如 Web服务器FTP服务器企业关键应用服务器其他主要任务服务器等上运行协同完成工作任务

2. “负载均衡” 的 分类 ?

  • 负载均衡 分为 “硬件” 负载均衡“软件” 负载均衡两种具体介绍如下 :

    (1) “硬件” 负载均衡解决方案就是直接服务器外部网络 之间 安装 “负载均衡设备”,通常这种设备称负载均衡器
    这样由 专门的设备 完成专门的任务负载均器独立于操作系统之外整体性能 得到大幅提高。加上多样化负载均衡策略智能化流量统计“硬件” 负载均衡解决方案 可达到 最佳负载均衡效果


    (2) “软件” 负载均衡解决方案是指在 一台多台服务器相应的 操作系统安装一个多个 "附加软件"来实现负载均衡
    DNS Load BalanceCheckPoint Firewall-1 ConnectControl 等。

    优点基于特定环境配置简单使用灵活成本低廉,可以 满足一般的负载均衡需求无论哪种负载均衡策略,都是为了系统高可用缓解网络压力以及扩容机器处理能力

  • 下面我们来看一个 使用 “负载均衡”Web架构具体如下图所示 :
    在这里插入图片描述

    上图所示架构中,负载均衡器维护一个可用的 “服务清单”,通过 心跳检测剔除故障服务端节点保证服务清单 中都是 可以正常访问服务器。当客户端借助网络 发送请求负载均衡器时,负载均衡器按照 “某种算法,从维护的服务清单里面"选择"
    一个服务器
    ,并将 客户端请求 "转发"到指定的服务器,从而提高 系统可用性稳定性

3. 认识 Ribbon :

3.1 Ribbon 的 含义

  • RibbonNetflix 公司的一款用于 客户端 负载均衡开源软件工具。它在集群中为 各个客户端通信 提供了 支持,有助于
    控制 HTTPTCP 客户端行为提供了很多 负载均衡算法,例如
    轮询
    随机算法等,同时也可以实现自定义的算法

3.2 Ribbon 的 实现 ( ①与 “RestTemplate” 相结合 ②与 “Feign” 相结合 )

  • Spring Cloud 构建的 微服务架构Ribbon 作为 服务消费者负载均衡器,有 两种 “使用方式” ( Ribbon 的 “实现方式” ):

    • (1) 一种与 RestTemplate 相结合

    • (2) 另一种与 Feign 相结合Feign已经默认集成RibbonRibbon 包含很多 “子模块”,但很多子块 没有用于生产环境。 目前 用于生产的Ribbon子模块 具体如下

      ① mibbon-core : 包括定义 负载均衡接口客户端接口内置负载均衡实现接口 等的 API
      ② ribbon-eureka : 提供 Eureka客户端 实现 "负载均衡"API
      ③ ribbon-httpclient : 对 ApacheHttpClient 进行封装。该
      模块
      提供了 含有 “负载均衡” 功能REST客户端。、

  • Spring Cloud 中,当 Ribbon ( 负载均衡 ) 和 Eureka ( 服务注册与发现 ) 配合使用的时候,Ribbon 可从 Eureka Server获取 服务提供者 “地址列表”,并 基于 “负载均衡算法”请求 其中一个 服务提供者实例

    Ribbon 整合 Eureka结构示例 如下图所示

    在这里插入图片描述

    上图可见该结构包含 一个 Eureka服务器 3个服务提供者以及 一个含有Ribbon服务消费者
    3个服务提供者Eureka服务器 "注册服务",当
    多个URL服务消费者 发起请求时,基于Ribbon负载均衡器 能够有效地将请求分摊不同的机器上

3.3 Nginx 与 Zookeeper 比较

  • NginxZookeeper 也是 可以作为 “负载均衡器” 使用 的,具体介绍如下 :

    (1) Nginx著名反向代理服务器,也被广泛地 作为 “负载均衡器” 使用。它的负载均衡配置非常简单Nginx配置
    多个Web服务器
    用户访问 Nginx 时,就会 自动被分配” 到 “某个Web 服务器


    (2) ZooKeeper“分布式协调服务” 框架,有时 也被用来作为 “负载均衡器” 使用ZooKeeper作为一个服务注册中心其中登记了每个服务每台服务器知道自己 “属于哪个服务”,在 服务器启动时,自己向所属服务进行登记

4. 第一个 Ribbon 实例 :

  • 服务 “注册与发现“ 框架 : Eureka框架 已经实现了Eureka高可用理论上使得微服务架构已经很完美了。但是, 考虑到机器自身硬件条件限制面对 流量高峰系统同样还会存在 宕机 等情况。此时,如果 使用 Ribbon “整合” Eureka “实现负载均衡”将用户请求 “分摊到” 多个服务器上,就能大幅减轻访问服务压力,使系统达到更好的负载能力
  • 下面我们将在 服务 “注册与发现“ 框架 : Eureka框架 搭建Eureka 集群 “基础上” 进行 改造具体步骤如下 :

4.1 改造 “服务提供者”

① 在 “服务提供者” 中 添加 Service层,创建 PortController控制器类
  • ( 前提 : 在 服务 “注册与发现“ 框架 : Eureka框架 敲的项目基础上进行关于 Ribbon 的开发 )

  • 我们服务消费者"集成Ribbon" 实现 客户端负载均。为了验证 服务消费者 调用的是 “哪个服务提供者” 的 服务,下面我们对 服务提供者进行改造改造后服务提供者 提供了"/port" API,用于 返回服务提供者端口号

  • 项目 : eureka-provider ( “第一个” 服务提供者 ) 和 eureka-provider-another ( “第二个” 服务提供者 ) 中 新建 controller包 ( 两个 “服务提供者” 项目中都加 ),并创建PortController类该类 能够 返回当前项目端口号具体代码如下所示 :

    PortController.java :

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /*
       @ResponseBody注解 :
        ①将方法的返回值转换为指定类型存入到"响应体"中响应给前端 :
          如果返回值为String类型,这个字符串会直接写入"响应体"中响应给前端( 不使用该注解时,String类型的返回值可以返回一个视图页面的,但现在没这个效果了 )
          如果返回值为"对象类型",会默认采用 MappingJackson2HttpMessageConverter 将该对象转换为"JSON格式的字符串",后写入"响应体"中响应给前端。
     */
    @ResponseBody
    @Controller //将该类加入到IOC容器中
    public class PortController { //返回当前项目的"端口号"
    
        @Value("${server.port}")//获取"全局配置文件"中的属性值,并将该属性值注入到下面这个属性中
        String port;
    
        @RequestMapping("/port")
        public String getPort() {
            return "Hello World,I'm from port: " + port;
        }
    
    }
    

4.2 搭建含有 Ribbon 的 “服务消费者” :

② 创建名称为 :eureka-ribbon-client 的Spring Boot 项目
  • 使用 Spring Initializr 方式创建一个名称eureka-ribbon-clientSpring Boot 项目。这里将 Group 命名为 com.myh , 将 Artifact 命名为 eureka-ribbon-client , 添加 Eureka ClientRibbonWeb 的 这 三个依赖项目创建好后pom.xml文件 代码 如下所示 :

    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 https://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>
            <!--    SpringBoot的版本为:2.1.7.RELEASE   -->
            <version>2.1.7.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.myh</groupId>
        <artifactId>eureka-ribbon-client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>eureka-ribbon-client</name>
        <description>eureka-ribbon-client</description>
        <properties>
            <java.version>1.8</java.version>
            <!--    Springcloud的版本为:Greenwich.SR2  -->
            <spring-cloud.version>GreenWich.SR2</spring-cloud.version>
        </properties>
    
        <dependencies>
    
            <!--  引入了 eureka-client 的jar包   -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!--  引入了 Ribbon(客户端的"负载均衡器") 依赖启动器 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
        <repositories>
            <repository>
                <id>spring-snapshots</id>
                <name>Spring Snapshots</name>
                <url>https://repo.spring.io/snapshot</url>
                <releases>
                    <enabled>false</enabled>
                </releases>
            </repository>
        </repositories>
        <pluginRepositories>
            <pluginRepository>
                <id>spring-snapshots</id>
                <name>Spring Snapshots</name>
                <url>https://repo.spring.io/snapshot</url>
                <releases>
                    <enabled>false</enabled>
                </releases>
            </pluginRepository>
        </pluginRepositories>
    
    </project>
    
③ “全局配置文件中” 配置信息
  • 全局配置文件 : application.yml中进行相关配置,包括指定 应用名称端口号服务注册地址 等信息具体代码如下所示

    application.yml :

    spring:
      application:
        name: eureka-ribbon-client #指定该应用的名为 : eureka-ribbon-client / 端口名称配置
    server:
      port: 8764 #指定该应用的端口号为 : 8764
    eureka:
      client:
          register-with-eureka: true  #表示将自己 "注册" 到"Eureka服务注册中心 / Eureka服务端" (默认值为true,所以该属性可省略不配置)
          fetch-registry: true  #表示 "从" EurekaSever 中获取 "注册信息" (默认值为true,所以该属性可省略不配置)
          service-url:
            defaultZone:
               http://localhost:7000/eureka/  #指定EurekaServer(服务注册中心)的地址
    
④ 在 “项目启动类” 中添加注解,开启Eureka Client 功能
  • 在 “项目启动类” 中 激活 Bureka Client相关配置 : 在项目启动类中 添加 @EnableEuekaClient注解,开启 Eureka Client 功能具体代码如下所示

    在这里插入图片描述

⑤ 创建 “RibbonConfg 配置类” ( 通过 与 “RestTemplate” 相结合来实现 “Ribbon负载均衡” )
  • 创建配置类,在 项目中新建 config,并在该包下创建 RibbonConfg。在 RibbonConfg类注入 restTemplateBean 对象,并在 Bean 对象加上 @LoadBalanced 注解具体代码如下所示

    RibbonConfig.java

    import org.springframework.boot.web.client.RestTemplateBuilder;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration //比较该类为"配置类"
    public class RibbonConfig { //Ribbon : 客户端"负载均衡器" 的 配置类
    
        @Bean //将该方法的返回值对象加入到IOC容器中
        @LoadBalanced // 该注解的作用 : 让 RestTemplate对象/RestTemplate实例 具备"负载均衡"的能力
        public RestTemplate restTemplate(RestTemplateBuilder builder) {
            //返回一个被 @LoadBalanced注解作用的 RestTemplate示例/RestTemplate对象
            //返回一个 具备 "负载均衡"能力的RestTemplate对象
            return builder.build();
        }
    }
    

    在上面的代码中,使用 @Confguration注解RibbonConfg类 “标注为” 配置类@Bean注解作用 : 将 restTemplate( )返回值 : RestTemplate 对象 加入到 IOC容器中@LoadBalanced 注解作用 :让 RestTemplate对象 具备 “负载均衡” 的 能力

⑥ 创建 Service层 , 创建 RibbonService业务类
  • 在 项目中新建 service包,并在该包下创建一个 RibbonService类。在 RibbonService 类hi( )方法中使用restTemplate对象调用eureka-clientAPI具体代码如下所示

    RibbonService.java :

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    @Service //加入ioc容器中
    public class RibbonService { //获得访问的"服务提供者"的端口号信息
    
        @Autowired
        RestTemplate restTemplate;
    
        public String hi() {
            /*
              getForObject()方法用于发起Get请求,
                第一个参数设置 : 请求的url ; 第二个参数指定 "返回结果" 的 Java类型,告诉 RestTemplate 将"响应体中的内容"转换为"指定类型"的对象。
    
              通过url请求访问到 "服务提供者"项目中的/port路径中,获得访问的"服务提供者"的端口信息
                ---(如果每次访问到的端口不是一样的,说明"负载均衡成功了")
             */
            return restTemplate.getForObject("http://eureka-provider/port",String.class); //String.class : 将响应体中内容转换为String类型
        }
    }
    
⑦ 创建 controller层 , 创建 RibbonService业务类
  • 项目中新建 controller在该包下新建一个 RibbonController。在该类上添加 @RestController 注解
    类中写一个 hi( )方法 , 通过该方法调用 RibbonServicehi( )方法具体代码如下所示 :

    import com.myh.eurekaribbonclient.service.RibbonService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController // = @@ResponseBody注解 + @Controller注解
    public class RibbonController { //该类为控制层类,可调用业务层中的代码
    
        @Autowired
        RibbonService ribbonService;
    
        @RequestMapping("/hi")
        public String hi() {
            //获得RibbonService业务类中的hi()方法的内容
            return ribbonService.hi();
        }
    }
    

4.3 测试运行

  • 启动 eureka-servereureka-server-another两个服务器( 服务器注册中心 ) , 启动 eureka-providereureka-provider-another两个 “服务提供者” 启动 服务消费者 : eurek-ribbon-client ( 该服务消费者配置Ribbon负载均衡器 )。

  • 浏览器上访问 http://server1:7000http://server2:7009 ( 这两个为 “服务注册中心” 的 访问url )。无论访问 “哪个Eureka Server”Eureka Server
    注册实例都是一样的,效果如下两图所示

    在这里插入图片描述


    在这里插入图片描述

    上两图看出,"两个"服务提供者"一个"服务消费者已经全部成功注册Eureka ( Eureka Server服务注册中心 )上,实现了高可用为了演示含有Ribbon服务消费者负载均衡效果,使用浏览器多次访问
    http://localhost:8764/hi ( localhost主机名8764端口号 , /hiurl请求 , 请求该项目中控制层中的 /hi路径下对应的方法 )

浏览器页面 访问效果如下图 所示 :

在这里插入图片描述


在这里插入图片描述

从上面两个图 可以看出,当访问 http://localhost:8764/hi 时,浏览器页面轮流显示两个服务提供者” 的 端口号说明负载均衡起了 效果负载均衡器轮流请求 两个服务提供者 中的 “hi”接口

5. Ribbon 的工作原理

  • 前面我们 使用Ribbon "实现负载均衡"时,基本用法注入一个 RestTemplate,并使用@LoadBalanced注解 标注RestTemplate,从而使 RestTemplate 具备 负载均衡能力

  • Spring容器启动,使用 @LoadBalanced注解 修饰RestTemplate 会被 添加到 “拦截器” 中,拦截器 中使用了
    LoadBalancerClient “处理请求”,从而 达到 负载均衡目的 。那么 LoadBalancerClient 内部如何做到的呢?
    下面我们通过 源码分析 的方式来 剖析 Ribbon负载均衡工作原理

  • LoadBalancerClientSpring Cloud 提供的一个非常重要接口,它 继承于 : ServicelnstanceChooser接口该接口实现类 是 : RibbonLoadBalanceClient,它们之间的 关系如下图所示 :

    在这里插入图片描述

  • 为了大家更好地理解中所示接口及其实现类实现细节,我们先来查看 LoadBalancerClient部分源码具体代码如下

    public interface LoadBalancerClient extends ServiceInstanceChooser {
        <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
    
        <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException;
    
        URI reconstructURI(ServiceInstance instance, URI original);
    }
    

    上述源码中LoadBalancerClient 提供的 “两个” execute( )方法 用于**执行请求** , reconstructURI ( )方法用于重构 URL


    继续査看 LoadBalancerClient 继承ServiceInstanceChooser接口源码具体代码如下 :

    public interface ServiceInstanceChooser {
        ServiceInstance choose(String serviceId);
    }
    

    上述源码中ServicelnstanceChooser接口定义了一个choose( )方法。该方法用于根据 serviceId选择一个服务实例,即通过服务名 “选择” 服务实例


  • RibbonLoadBalanceClientLoadBalancerClient实现类,它用来 执行最终负载均衡请求RibbonLoadBalanceClient 中的 choose( )方法用于选择具体的 服务实例,其内部是通过 getServer( )方法交给ILoadBalancer接口 完成的。


    ILoadBalancer 是一个接口,该接口定义了一系列 “实现负载均衡” 的 方法IoadBalancer 接口实现类结构如下图所示

    在这里插入图片描述

    查看 BaseLoadBalancerDynamicServerListLoadBalancer 源码默认情况实现了以下配置

    • (1) IClientConfg clientConfg : 用于配置 “负载均衡客户端默认实现类DefaultClientConfglmpl
    • (2) IRule rule : 用于配置 负载均衡策略默认使用的是 RoundRobinRule 策略,也就是轮询策略
    • (3) IPing ping : 用于检查当前服务是否有响应”,从而判断当前服务是否可用”。默认实现类DummyPing。该 实现类isAlive( )方法返回值true,即 默认所有服务实例都是可用
    • (4) ServerList serverList : 用于获取所有 Server注册列表信息ServerList实现类DiscoveryEnabledNIWSServerList。该类定义obtainServersViaDiscovery( )方法根据 eurekaClientProvider.get()法获取 EurekaClient,再根据 EurekaClient 获取服务注册列表信息”。EurekaClient实现类DiscoveryClientDiscoveryClient 具有服务注册获取服务注册列表 等功能。
    • (5)ServerListFilter flter : 定义了根据 配置过滤者动态获取符合条件服务列表默认实现类ZonePreferenceServerListFilter。该策略能够优先过滤出” 与请求调用方处于同区域服务实例

    综上所述,使用 RibbonLoadBalanceClient 实现"负载均衡"时,会从 EurekaClient 获取 “服务列表信息”,然后根据 IPing 判断服务 “是否可用如果服务可用,就会根据 IRule 选择 "负载均衡策略",否则会 “重新获取” 服务清单


  • 了解了 LoadBalancerClient 负载均衡功能后,那么ResrTemplate 添加 @LoadBalanced 注解后 为什么会被拦截呢?
    这是因为 LoadBalancerAutoConfiguration类维护了一个被 @LoadBalaneed 注解修饰的 ResTemplate 列表,在
    初始化过程中,通过
    调用 customizer.customize( resTemplate )方法
    RestTemplate 添加
    LoadBalancerlnterceptor拦截器,该拦截器中的方法远程服务调用的方法 交给了 LoadBalancerClient 去处理
    从而达到了 负载均衡目的

6. Ribbon 负载均衡策略

  • 默认情况下Ribhon 使用的 负载均衡策略轮询策略。实际上,Ribbon 提供了 很多 负载均衡算法 ,其中 IRue 接口就是 所有负载均衡算法父接口 , 它的实现类结构 如下图所示 :

    在这里插入图片描述

    在上图中AbstractLoadBalancerRule负载均衡策略抽象类。该抽象类定义了负载均衡器 : IoaderBalancer对象 ,对象能够 在具体 实现 "选择服务策略"时,获取到一些负载均衡器维护的信息该信息会作为 选择 "服务策略"时的分配依据,并以此设计一些算法来实现针对特定场景高效策略

  • 在上图中各个实现类实现了一种负载均衡算法,关于这些实现类具体介绍如下 :

    • RoundRobinRule :
      实现了按 “照线性轮询” 的方式 依次选择服务 的功能。
    • WeightedResponseTimeRule :
      RoundRobinRule扩展,会根据平均响应时间 “计算” 所有服务的 “权重”响应时间越快服务权重越大被选中的概率越高
    • ZoneAvoidanceRule :
      它是 PredicateBasedRue具体实现类。其内部通过使用 ZoneAvoidancePredicateAvailabilityPredicate 判断 ”是否选择“ 某个服务前者用于判断服务所在区域的性能是否可用”,后者用于 “过滤掉 连接数过多的服务
    • AvailabilityFilteringRule :
      使用 AvailabilityPredicate 过滤 由于 多次访问出现故障而处于断路器跳闸状态服务,还有 并发的连接数 "超过阈值"服务,然后对 剩余的服务列表进行 轮询
    • BestAvailableRule :
      用于 先过滤掉多次访问出现故障而处于断路跳闸状态服务,然后选择一个 并发量最小服务
    • RetryRule :
      该策略实现了一个 具备 “重试功能”服务选择功能,其内部会"先按照轮询策略" 获取服务如果获取失败就在
      指定时间内重试
      获取可用服务
    • RandomRule :
      该策略实现了从服务清单中随机选择一个服务的功能。
    • ClientConfgEnableRoundRobinRule :
      该类是一个 抽象类。该类本身没有实现特殊处理逻辑,我们 也不会直接使用该策略,但是通过使用 BestAvailableRule继承该策略 默认实现线性轮询。它的内部定义了一个RoundRobinRule 策略
    • PredicateBasedRule : 继承ClientConfgEnableRoundRobinRule,其内部会先通过
      chooseRoundRobinAferFiltering( ) 方法筛选服务清单”,然后以 线性轮询的方式从 过滤后的服务清单选择一个服务
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值