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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM