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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章