09、SpringCloud实战:Ribbon负载均衡

目录

一、Ribbon负载均衡策略(常用7种):

详细介绍:

1、 轮询策略:RoundRibbonRule(Ribbon默认策略);

2、 重试策略:RetryRule;

3、 加权响应时间策略:WeightedResponseTimeRule;

4、 随机策略:RandomRule;

5、 最空闲策略:BestAvailableRule;

6、 区域感知轮询策略:ZoneAvoidanceRule;

7、 可用性过滤策略:AvailabilityFilteringRule;

二、Ribbon的使用(不需要引入新的依赖,因为ribbon集成在了eureka client中了)

1、 在手动注入RestTemplate时添加注解@LoadBalanced开启ribbon负载均衡;

2、 在member项目的controller中添加新的接口;

3、 运行springcloud-eureka、springcloud-order(启动三个服务实例)、springcloud-member启动类;

4、 多次访问localhost:9081/member/getOrder;

三、修改Ribbon的轮询策略

1、 全局修改,即所有的服务都是用同一个负载均衡策略;

2、 局部修改,即不同的服务使用不同的负载均衡策略;

2、 1基于注解的方式配置;

2、 2基于配置文件的方式配置;

四、自定义负载均衡策略


一、Ribbon负载均衡策略(常用7种):

1、 轮询策略:RoundRibbonRule(Ribbon默认策略);

2、 重试策略:RetryRule;

3、 权重轮询策略:WeightedResponseTimeRule;

4、 随机策略:RandomRule;

5、 最少并发数策略:BestAvailableRule;

6、 区域感知轮询策略:ZoneAvoidanceRule;

7、 可用性过滤策略:AvailabilityFilteringRule;

*

详细介绍:

1、轮询策略: RoundRibbonRule(Ribbon默认策略)

BaseLoadBalancer 负载均衡器默认采用线性负载轮询负载均衡策略。

工作流程:

RoundRibbonRule 类的 choose(ILoadBalancer Ib,Object key) 方法初始化一个计数器。

incrementAndGetModulo() 方法获取一个下标 (是先加1,然后和服务清单总数取模获取到的,不会越界),是一个不断增长的数。

chooseServer(Object key) 方法拿着下标去服务列表中获取服务,每次循环计数器都会加1。如果连续10次都没有取到服务,则会报 “No available alive servers after 10 tries from loadbalancer.” 警告。

2、重试策略:RetryRule

重试策略在使用 RetryRule 类中定义的 choose(ILoadBalance Ib,Object key) 方法来选择一个服务实例。

choose() 方法也是采用 RoundRibbonRule 中的 choose() 方法来选择一个服务实例的。

工作流程

如果选择到的服务实例正常,则返回数据。

如果选择到的服务实例为 null 或 失效,则 choose() 方法会在失效时间前不断地进行重试。

如果超过了失效时间还是没有取到,则返回一个 null。

3、加权响应时间策略:WeightedResponseTimeRule

WeightedResponseTimeRule 类是 RoundRibbonRule 的一个子类,它对 RoundRibbonRule 的功能进行了扩展。它根据每一个服务实例的运行情况先计算出该服务实例的一个权重,然后根据权重进行服务实例的挑选,这样能够调用到更优的服务实例。

工作流程

每30S 计算一次各服务实例的响应时间,以响应时间来计算权重。平均响应时间越短则权重越高,权重越高则被选中的的概率越高,反之则被选中的概率较低。

WeightedResponseTimeRule 中有一个名叫 DynamicServerWeightTask 的定时任务。它是一个后台线程,定期从 status 里面读取响应时间,用来计算每个服务实例权重。

4、随机策略:RandomRule

随机选择一个可用的服务实例。

工作流程

负载均衡通过 upList() 和 allList() 方法获得可用服务实例列表,然后初始化了一个 Randow 对象以生成一个不大于服务实例总的随机数。

choose() 方法将该随机数作为下标获取一个服务实例。轮询 “index” 选择 “index” 对应的服务实例。

5、最空闲策略:BestAvailableRule

该服务是逐个考察各服务实例,然后选择一个最小的并发请求的服务实例来提供实例。BestAvailableRule 继承自 ClientConfigEnabledRoundRobbinRule 类。

工作流程

根据在loadBalancerStats() 方法中保存的服务实例的状态信息来过滤失效的服务实例。

判断loadBalancerStats 是否为空。

如果loadBalancerStats 不为空,则找出并发请求最小的服务实例来使用。

如果loadBalancerStats 为空,则 BestAvailableRule 类将采用它的父类。即 ClientConfigEnabledRoundRobbinRule 的服务选取策略 (线性策略)。

6、区域感知轮询策略:ZoneAvoidanceRule

该策略以区域、可用的服务器为基础,选择服务实例并对服务实例进行分类。ZoneAvoidanceRule 类是 PredicateBasedRule 类的一个实现类,它有一个组合过滤条件 (CompositePredicate)。ZoneAvoidanceRule 类中的过滤条件是 “以 ZoneAvoidancePredicate() 方法为主过滤条件” 和 “以AvailabilityPredicate() 方法为次过滤条件” 组成的。在过滤成功后,继续采用线性轮询的方式从过滤结果中选择出一个服务实例。

7、可用性过滤策略:AvailabilityFilteringRule

该策略根据服务状态 (宕机和繁忙) 来分配权重,过滤掉那些因为一直连接失败或高并发的服务实例。它使用一个 AvailabilityPredicate() 方法来包含过滤逻辑。

8、 过滤性线性轮询策略:PredicateBasedRule;

PredicateBaseRule 类是 ClientConfigEnabledRoundRobbinRule 类的一个子类,它通过内部定义的一个过滤器过滤出一部分服务实例清单,然后用线性轮形的方式从过滤出来的服务实例清单中选取提个服务实例。

9、 客户端配置启动线性轮询策略:ClientConfigEnabledRoundRobbinRule;

继承该策略默认的 choose() 方法就能实现线性轮询机制。

二、Ribbon的使用(不需要引入新的依赖,因为ribbon集成在了eureka client中了)

*

1、在手动注入RestTemplate时添加注解@LoadBalanced开启ribbon负载均衡

// 手动注入RestTemplate实例
@Bean
//Ribbon负载均衡集成在了Eureka中
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

2、在member项目的controller中添加新的接口

@RestController
@RequestMapping("/member")
public class MemberController {
    @GetMapping("/getOrder")
    public String getOrder() {
        //URL的host使用服务名称(服务id)即可,不需要指定端口号,由loadBalance根据负载均衡策略决定具体的服务调用
        return template.getForObject("http://server-order/order/getOrderInfo", String.class);
    }
}

*

3、运行springcloud-eureka、springcloud-order(启动三个服务实例)、springcloud-member启动类

*

4、多次访问localhost:9081/member/getOrder

*

*

*

此时,使用ribbon默认的负载均衡策略轮询的方式访问远程接口

三、修改Ribbon的轮询策略

1、全局修改,即所有的服务都是用同一个负载均衡策略

在member项目的启动类中添加Bean(IRule),然后重启该服务即可

// 设置负载均衡策略为随机,默认为轮询(全局设置)
@Bean
public IRule rule(){
    return new RandomRule();
}

再次访问localhost:9081/member/getOrder,可以看到端口号从9071、9072、9073三个服务中随机选择访问

2、局部修改,即不同的服务使用不同的负载均衡策略

2.1 基于注解的方式配置

第一步:新建两个class类,OrderConfig 、PayConfig

//单独设置服务的负载均衡策略(代码方式)
public class OrderConfig {
    //设置order服务负载均衡策略为随机
    @Bean
    public IRule orderRule() {
        return new RandomRule();
    }
}
//单独设置服务的负载均衡策略(代码方式)
public class PayConfig {
    //设置pay服务负载均衡策略为轮询
    @Bean
    public IRule payRule() {
        return new RoundRobinRule();
    }
}

第二步:在启动类中添加注解@RibbonClients

//单独设置具体服务的负载均衡策略
@RibbonClients({@RibbonClient(name = "server-order",configuration = OrderConfig.class),
        @RibbonClient(name = "server-pay",configuration = PayConfig.class)})

*

第三步:重启服务,再次访问接口,即可看到对应的访问效果

2.2 基于配置文件的方式配置

在member项目的application中添加以下配置

#按照服务模块提供不同的负载均衡策略,如果有自定义的策略,只需要配置在NFLoadBalancerRuleClassName即可
server-order:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

server-pay:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

*

注释掉启动类上的注解@RibbonClients,然后重启服务,重新访问即可验证。

如果同一个服务注解和配置文件配置的负载均衡策略不一样,注解配置的会覆盖配置文件配置的策略,即以注解配置的为准

项目中一般使用基于配置文件的形式配置负载均衡策略,一方面各个服务的访问策略一目了然,方便管理以及修改,另一方面使用注解方式的话修改完了需要重新打包部署比较麻烦

四、自定义负载均衡策略

参照com.netflix.loadbalancer.RandomRule和com.netflix.loadbalancer.RoundRobinRule的写法,照葫芦画瓢,继承AbstractLoadBalancerRule类即可,具体实践暂不深究

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: