• SpringCloud的Ribbon自定义负载均衡算法


    1.Ribbon默认使用RoundRobinRule策略轮询选择server

    策略名 策略声明 策略描述 实现说明
    BestAvailableRule
    public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule
    选择一个最小的并发请求的server 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
    AvailabilityFilteringRule public class AvailabilityFilteringRule extends PredicateBasedRule 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) 使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
    WeightedResponseTimeRule public class WeightedResponseTimeRule extends RoundRobinRule 根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。 一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成status时,使用roubine策略选择server。
    RetryRule public class RetryRule extends AbstractLoadBalancerRule 对选定的负载均衡策略机上重试机制 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
    RoundRobinRule public class RoundRobinRule extends AbstractLoadBalancerRule roundRobin方式轮询选择server 轮询index,选择index对应位置的server
    RandomRule
    public class RandomRule extends AbstractLoadBalancerRule

    随机选择一个server

    在index上随机,选择index对应位置的server

    ZoneAvoidanceRule

    public class ZoneAvoidanceRule extends PredicateBasedRule

    复合判断server所在区域的性能和server的可用性选择server

    使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

            切换策略

      

    1.  
      @Configuration
    2.  
      public class ConfigBean {
    3.  
       
    4.  
      // @Bean
    5.  
      // public RestTemplate getRestTemplate() {
    6.  
      // return new RestTemplate();
    7.  
      // }
    8.  
       
    9.  
      @Bean
    10.  
      @LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。
    11.  
      public RestTemplate getRestTemplate() {
    12.  
      return new RestTemplate();
    13.  
      }
    14.  
       
    15.  
      @Bean
    16.  
      public IRule myRule()
    17.  
      {
    18.  
      //return new RoundRobinRule();
    19.  
      // return new RandomRule();//达到的目的,用我们重新选择的随机算法替代默认的轮询。
    20.  
      return new RetryRule();
    21.  
      }
    22.  
      }

         自定义算法:

          配置类(必须不能在启动类和启动类下所包含的子包下面)

    1.  
      public class RandomRule_ZY extends AbstractLoadBalancerRule
    2.  
      {
    3.  
       
    4.  
      // total = 0 // 当total==5以后,我们指针才能往下走,
    5.  
      // index = 0 // 当前对外提供服务的服务器地址,
    6.  
      // total需要重新置为零,但是已经达到过一个5次,我们的index = 1
    7.  
      // 分析:我们5次,但是微服务只有8001 8002 8003 三台,OK?
    8.  
      //
    9.  
       
    10.  
       
    11.  
      private int total = 0; // 总共被调用的次数,目前要求每台被调用5次
    12.  
      private int currentIndex = 0; // 当前提供服务的机器号
    13.  
       
    14.  
      public Server choose(ILoadBalancer lb, Object key)
    15.  
      {
    16.  
      if (lb == null) {
    17.  
      return null;
    18.  
      }
    19.  
      Server server = null;
    20.  
       
    21.  
      while (server == null) {
    22.  
      if (Thread.interrupted()) {
    23.  
      return null;
    24.  
      }
    25.  
      List<Server> upList = lb.getReachableServers();
    26.  
      List<Server> allList = lb.getAllServers();
    27.  
       
    28.  
      int serverCount = allList.size();
    29.  
      if (serverCount == 0) {
    30.  
      /*
    31.  
      * No servers. End regardless of pass, because subsequent passes only get more
    32.  
      * restrictive.
    33.  
      */
    34.  
      return null;
    35.  
      }
    36.  
       
    37.  
      // int index = rand.nextInt(serverCount);// java.util.Random().nextInt(3);
    38.  
      // server = upList.get(index);
    39.  
       
    40.  
       
    41.  
      // private int total = 0; // 总共被调用的次数,目前要求每台被调用5次
    42.  
      // private int currentIndex = 0; // 当前提供服务的机器号
    43.  
      if(total < 5)
    44.  
      {
    45.  
      server = upList.get(currentIndex);
    46.  
      total++;
    47.  
      }else {
    48.  
      total = 0;
    49.  
      currentIndex++;
    50.  
      if(currentIndex >= upList.size())
    51.  
      {
    52.  
      currentIndex = 0;
    53.  
      }
    54.  
      }
    55.  
       
    56.  
       
    57.  
      if (server == null) {
    58.  
      /*
    59.  
      * The only time this should happen is if the server list were somehow trimmed.
    60.  
      * This is a transient condition. Retry after yielding.
    61.  
      */
    62.  
      Thread.yield();
    63.  
      continue;
    64.  
      }
    65.  
       
    66.  
      if (server.isAlive()) {
    67.  
      return (server);
    68.  
      }
    69.  
       
    70.  
      // Shouldn't actually happen.. but must be transient or a bug.
    71.  
      server = null;
    72.  
      Thread.yield();
    73.  
      }
    74.  
       
    75.  
      return server;
    76.  
       
    77.  
      }
    78.  
       
    79.  
      @Override
    80.  
      public Server choose(Object key)
    81.  
      {
    82.  
      return choose(getLoadBalancer(), key);
    83.  
      }
    84.  
       
    85.  
      @Override
    86.  
      public void initWithNiwsConfig(IClientConfig clientConfig)
    87.  
      {
    88.  
      // TODO Auto-generated method stub
    89.  
       
    90.  
      }
    91.  
       
    92.  
      }
    1.  
      @Configuration
    2.  
      public class MySelfRule {
    3.  
      @Bean
    4.  
      public IRule myRule() {
    5.  
      // return new RandomRule();// Ribbon默认是轮询,我自定义为随机
    6.  
      return new RandomRule_ZY();// 我自定义为每台机器5次
    7.  
      }
    8.  
      }

            另一配置类(在启动类包里面)

    1.  
      @Configuration
    2.  
      public class ConfigBean {
    3.  
       
    4.  
      // @Bean
    5.  
      // public RestTemplate getRestTemplate() {
    6.  
      // return new RestTemplate();
    7.  
      // }
    8.  
       
    9.  
      @Bean
    10.  
      @LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。
    11.  
      public RestTemplate getRestTemplate() {
    12.  
      return new RestTemplate();
    13.  
      }
    14.  
       
    15.  
      // @Bean
    16.  
      // public IRule myRule()
    17.  
      // {
    18.  
      // //return new RoundRobinRule();
    19.  
      // return new RandomRule();//达到的目的,用我们重新选择的随机算法替代默认的轮询。
    20.  
      // return new RetryRule();
    21.  
      // }
    22.  
      }

            启动类

    1.  
      @SpringBootApplication
    2.  
      @EnableEurekaClient
    3.  
      //在启动该微服务的时候就能去加载我们的自定义Ribbon配置类,从而使配置生效
    4.  
      //@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
    5.  
      @RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
    6.  
      public class DeptConsumer80_App {
    7.  
      public static void main(String[] args) {
    8.  
      SpringApplication.run(DeptConsumer80_App.class, args);
    9.  
      }
    10.  
      }

    测试效果为每个server执行5次再轮询

    转自:https://blog.csdn.net/flynn_chen/article/details/80631717

  • 相关阅读:
    [大牛翻译系列]Hadoop(4)MapReduce 连接:选择最佳连接策略
    [大牛翻译系列]Hadoop(2)MapReduce 连接:复制连接(Replication join)
    [大牛翻译系列]Hadoop(3)MapReduce 连接:半连接(Semijoin)
    [大牛翻译系列]Hadoop(1)MapReduce 连接:重分区连接(Repartition join)
    Springboot启动流程分析
    行为型模式模板&策略&命令
    Springboot自动装配原理
    Springboot零配置原理
    行为型模式中介者&迭代器&访问者
    结构型模式组合&享元
  • 原文地址:https://www.cnblogs.com/dauber/p/9443072.html
Copyright © 2020-2023  润新知