Spring Cloud:自定义 Ribbon 负载均衡策略

1.在启动类使用注解@RibbonClient注解,name属性为serviceID,configration属性为自定义的配置类

@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "MICROSERVICE-ORDER", configuration = MyRuleConfig.class)
public class OrderConsumer {

   public static void main(String[] args) {
       SpringApplication.run(OrderConsumer.class, args);
   }
}

2.自定义配置

/**
* 自定义配置
*/
@Configuration
public class MyRuleConfig {
   @Bean
   public IRule myselfRule() {
       // 指定策略:我们自定义的策略
       return new CustomRule();
   }
}

3.如果我们想编写我们自己的负载规则

a.继承AbstractLoadBalancerRule

b.重写choose方法

/**
* 自定义规则
*/
public class CustomRule extends AbstractLoadBalancerRule {

   /**
    * 总共被调用的次数,目前要求每台被调用4次
     */
   private int total = 0;
   /**
    * 当前提供服务列表的索引
    */
   private int currentIndex = 0;

   @Override public void initWithNiwsConfig(IClientConfig iClientConfig) {
   }

   /**
    * 在choose方法中,自定义我们自己的规则,返回的Server就是具体选择出来的服务
    * 自己的规则:按照轮询的规则,但是每个被轮询到的服务调用5次。
    * @param o
    * @return
    */
   @Override public Server choose(Object o) {
       // 获取负载均衡器lb
       ILoadBalancer lb = getLoadBalancer();
       if (lb == null) {
           return null;
       }

       Server server = null;
       while (server == null) {
           if (Thread.interrupted()) {
               return null;
           }
           // 获取可用服务列表
           List<Server> upList = lb.getReachableServers();
           // 获取所有服务列表
           List<Server> allList = lb.getAllServers();
           int serverCount = allList.size();
           if (serverCount == 0) {
               return null;
           }

           // 若调用次数小于4次,一直调用可用服务列表中索引为 currentIndex 的服务
           if(total < 4)
           {
               server = upList.get(currentIndex);
               total++;
           } else {
               // 到了4次之后,服务列表中的索引值++,表示下一个调用下一个服务
               total = 0;
               currentIndex++;
               // 当索引大于可用服务列表的size时,要重新从头开始
               currentIndex = currentIndex % upList.size();

               if (server == null) {
                   Thread.yield();
                   continue;
               }

               if (server.isAlive()) {
                   return (server);
               }

               server = null;
               Thread.yield();
           }
       }
       return server;
   }
}

注意点:

1.自定义配置文件,不要放在启动类同包及其子包小,否则被@ComponetScan扫描到会导致所有的RibbonClient都去共享这个配置。

解决方法:配置在外面;

或者在扫描过程中,跳过该配置。

public @interface ExcudeAnnotatio {

}


@ComponentScan(basePackages = "com.foo.bar", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = ExcudeAnnotatio.class)}) //不扫描带有@ExcudeAnnotatio注解的配置(也可以直接过滤类)

2.默认的负载规则都有哪些?

 

3.除了java配置,还有没有其它的方法

4.网上看到的有关重试的坑。原因是:查询时间过长,导致接口响应时间长,触发了重试。

我们在使用Ribbon或者Feigin的时候,是可以开启超时重试功能的,网上很多资料都会讲到,这里就不啰嗦了。

那么我们要关闭这个功能呢?


开启的配置如下(另外ribbon超时时间和断路器超时时间也需要配置)

spring.cloud.loadbalancer.retry.enabled=true

ribbon.ReadTimeout=90000

ribbon.ConnectTimeout=10000

#Hystrix超时时间(默认1000ms,单位:ms)

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=95000

# 同一实例最大重试次数,不包括首次调用

ribbon.MaxAutoRetries=1

# 重试其他实例的最大重试次数,不包括首次所选的server

ribbon.MaxAutoRetriesNextServer= 2

# 是否所有操作都进行重试

ribbon.OkToRetryOnAllOperations=true

 


当我们需要关闭重试功能的时候,是不是spring.cloud.loadbalancer.retry.enabled=false就可以了呢,并不是。

需要把ribbon.OkToRetryOnAllOperations=false才行。

这里有人详细分析过,https://www.cnblogs.com/zhangjianbin/p/7228628.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值