日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

1.Ribbon介紹

因為微服務是目前互聯網公司比較流行的架構,所以spring就提供了一個頂級框架-spring cloud,來解決我們在開發微服務架構中遇到的各種各樣的問題,今天的主角是spring cloud 框架中集成的組件Ribbon,那么Ribbon能解決什么問題呢,我們來思考下面的問題。

? 微服務架構中的每個服務為了高可用,很大程度上都會進行集群,我們假設現在集群了3個user服務,同時能提供相同的服務,問題來了,我們如何決定調用這3個user服務中的哪一個呢?

? 根據不同分析角度,會有不同的答案,也可以理解為根據不同的情況,我們可以寫不同的算法,來決定到底此時此刻,調用這3個user服務的哪一個,那么,Ribbon就給我們提供了不同的算法,我們可以根據業務場景,調整配置文件,決定到底使用哪個算法,這樣,算法中就會計算出調用哪個user服務了。

2.準備工作

1)我們準備一個eureka注冊中心

2)再準備一個order服務

3)再準備3個相同代碼的user服務,這樣,order服務通過eureka注冊中心,就可以發現user的3個服務

3.Ribbon的常用負載均衡策略

Ribbon是通過IRule的這個接口來選擇3個user服務中的哪個的,但是實際執行的代碼肯定是繼承了這個接口的實現類,所以選擇不同的實現類,就會選擇不同負載均衡策略

public interface IRule {

    Server choose(Object var1);

    void setLoadBalancer(ILoadBalancer var1);

    ILoadBalancer getLoadBalancer();
}

3.1. RoundRobinRule 輪詢策略

此策略是Ribbon的默認策略,是按照順序,依次對所有的user服務進行訪問。

通過重寫IRule的choose方法,來選擇并返回決定調用的user服務,在下面的源碼中,List allServers = lb.getAllServers(); 獲得了所有的3個user服務實例,int nextServerIndex = this.incrementAndGetModulo(serverCount); 保存了當前調用的user實例的序號,然后就可以按照順序調用下一個user服務了

public Server choose(ILoadBalancer lb, Object key) {
    if (lb == null) {
        log.warn("no load balancer");
        return null;
    } else {
        Server server = null;
        int count = 0;

        while(true) {
            if (server == null && count++ < 10) {
                List<Server> reachableServers = lb.getReachableServers();
                List<Server> allServers = lb.getAllServers();
                int upCount = reachableServers.size();
                //總服務實例數量
                int serverCount = allServers.size();
                if (upCount != 0 && serverCount != 0) {
                    int nextServerIndex = this.incrementAndGetModulo(serverCount);
                    server = (Server)allServers.get(nextServerIndex);
                    if (server == null) {
                        Thread.yield();
                    } else {
                        if (server.isAlive() && server.isReadyToServe()) {
                            return server;
                        }

                        server = null;
                    }
                    continue;
                }

                log.warn("No up servers available from load balancer: " + lb);
                return null;
            }

            if (count >= 10) {
                log.warn("No available alive servers after 10 tries from load balancer: " + lb);
            }

            return server;
        }
    }
}

debug的圖例:

ribbon的常用負載均衡算法分析

 

3.2. RoundRobinRule 隨機策略

就和這個策略的名字一樣,是對user的3個服務的隨機調用,所以不存在規律,如下源碼中int index = this.chooseRandomInt(serverCount); 通過隨機數來選擇下標,所以對user服務的調用是隨機的

public Server choose(ILoadBalancer lb, Object key) {
    if (lb == null) {
        return null;
    } else {
        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;
            }

            int index = this.chooseRandomInt(serverCount);
            server = (Server)upList.get(index);
            if (server == null) {
                Thread.yield();
            } else {
                if (server.isAlive()) {
                    return server;
                }

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

        return server;
    }
}

debug的圖例:

ribbon的常用負載均衡算法分析

 

3.3. WeightedResponseTimeRule響應時間加權重策略

根據user的3個服務的響應時間來分配權重,響應時間越長的服務,權重越低,那么被調用的概率也就越低。相反,響應時間越短的服務,權重越高,被調用的概率也就越高

響應時間加權重策略的實現分為兩步:

  1. WeightedResponseTimeRule實現類中默認情況下每隔30秒會統計一次每個服務的權重,在此30秒內,用的是輪詢策略
  2. 30秒之后,會根據統計的結果來分配每個實例的權重,然后根據權重來分配調用次數
extends RoundRobinRulepublic Server choose(ILoadBalancer lb, Object key) {
    if (lb == null) {
        return null;
    } else {
        Server server = null;

        while(server == null) {
            List<Double> currentWeights = this.accumulatedWeights;
            if (Thread.interrupted()) {
                return null;
            }

            List<Server> allList = lb.getAllServers();
            int serverCount = allList.size();
            if (serverCount == 0) {
                return null;
            }

            int serverIndex = 0;
            double maxTotalWeight = currentWeights.size() == 0 ? 0.0D : (Double)currentWeights.get(currentWeights.size() - 1);
            //在30秒之內,maxTotalWeight變量會一直是0.0
            if (maxTotalWeight >= 0.001D && serverCount == currentWeights.size()) {
                double randomWeight = this.random.nextDouble() * maxTotalWeight;
                int n = 0;

                for(Iterator var13 = currentWeights.iterator(); var13.hasNext(); ++n) {
                    Double d = (Double)var13.next();
                    if (d >= randomWeight) {
                        serverIndex = n;
                        break;
                    }
                }

                server = (Server)allList.get(serverIndex);
            } else {
                server = super.choose(this.getLoadBalancer(), key);
                if (server == null) {
                    return server;
                }
            }

            if (server == null) {
                Thread.yield();
            } else {
                if (server.isAlive()) {
                    return server;
                }

                server = null;
            }
        }

        return server;
    }
}

debug的圖例:

ribbon的常用負載均衡算法分析

 

3.4. RetryRule 重試策略

重試策略是指通過輪詢策略選出一個實例,然后去訪問,如果此實例為null或者已經失效,那么會重試其他的實例,answer = this.subRule.choose(key); 會根據輪詢策略選擇一個實例,然后if ((answer == null || !answer.isAlive()) && System.currentTimeMillis() < deadline)判斷如果實例為null或者失效,那么會重新選擇

public Server choose(ILoadBalancer lb, Object key) {
    long requestTime = System.currentTimeMillis();
    long deadline = requestTime + this.maxRetryMillis;
    Server answer = null;
    answer = this.subRule.choose(key);
    if ((answer == null || !answer.isAlive()) && System.currentTimeMillis() < deadline) {
        InterruptTask task = new InterruptTask(deadline - System.currentTimeMillis());

        while(!Thread.interrupted()) {
            answer = this.subRule.choose(key);
            if (answer != null && answer.isAlive() || System.currentTimeMillis() >= deadline) {
                break;
            }

            Thread.yield();
        }

        task.cancel();
    }

    return answer != null && answer.isAlive() ? answer : null;
}
ribbon的常用負載均衡算法分析

 

3.5. BestAvailableRule 最低并發策略

會根據每個服務實例的并發數量來決定,訪問并發數最少的那個服務,int concurrentConnections = serverStats.getActiveRequestsCount(currentTime); 會獲得當前遍歷的實例的并發數,然后和其他的實例的并發數進行判斷,最終訪問并發量最少的那個實例

public Server choose(Object key) {
    if (this.loadBalancerStats == null) {
        return super.choose(key);
    } else {
        List<Server> serverList = this.getLoadBalancer().getAllServers();
        int minimalConcurrentConnections = 2147483647;
        long currentTime = System.currentTimeMillis();
        Server chosen = null;
        Iterator var7 = serverList.iterator();

        while(var7.hasNext()) { //遍歷所有的實例
            Server server = (Server)var7.next();
            ServerStats serverStats = this.loadBalancerStats.getSingleServerStat(server);
            if (!serverStats.isCircuitBreakerTripped(currentTime)) {
                int concurrentConnections = serverStats.getActiveRequestsCount(currentTime); //判斷并發數,并和已經判斷出的最少的并發數比較
                if (concurrentConnections < minimalConcurrentConnections) {
                    minimalConcurrentConnections = concurrentConnections;
                    chosen = server;
                }
            }
        }

        if (chosen == null) {
            return super.choose(key);
        } else {
            return chosen;
        }
    }
}

3.6. AvailabilityFilteringRule 可用過濾策略

此策略會聰明的過濾掉一直失敗并被標記為circuit tripped的user服務,而且會過濾掉那些高并發的user服務

public Server choose(Object key) {
    int count = 0;

    for(Server server = this.roundRobinRule.choose(key); count++ <= 10; server = this.roundRobinRule.choose(key)) {
        //通過predicate來過濾
        if (this.predicate.Apply(new PredicateKey(server))) {
            return server;
        }
    }
    //過濾掉一些服務之后,會采用輪詢的方式調用剩下的服務
    return super.choose(key);
}

3.7. ClientConfigEnabledRoundRobinRule 自定義策略

此策略本身并沒有實現什么特殊的處理邏輯,但是可以通過重置LoadBalancer來達到自定義一些高級策略的目的,可以重寫initWithNiwsConfig和setLoadBalancer

public void initWithNiwsConfig(IClientConfig clientConfig) {
    this.roundRobinRule = new RoundRobinRule();
}

public void setLoadBalancer(ILoadBalancer lb) {
    super.setLoadBalancer(lb);
    this.roundRobinRule.setLoadBalancer(lb);
}

public Server choose(Object key) {
    if (this.roundRobinRule != null) {
        return this.roundRobinRule.choose(key);
    } else {
        throw new IllegalArgumentException("This class has not been initialized with the RoundRobinRule class");
    }
}

分享到:
標簽:Ribbon
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定