亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java負(fù)載均衡算法實(shí)現(xiàn)之輪詢和加權(quán)輪詢

 更新時(shí)間:2022年04月12日 07:49:26   作者:持行非就  
網(wǎng)上找了不少負(fù)載均衡算法的資源,都不夠全面,后來自己結(jié)合了網(wǎng)上的一些算法實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Java負(fù)載均衡算法實(shí)現(xiàn)之輪詢和加權(quán)輪詢的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

1.普通輪詢算法

輪詢(Round Robin,RR)是依次將用戶的訪問請求,按循環(huán)順序分配到web服務(wù)節(jié)點(diǎn)上,從1開始到最后一臺服務(wù)器節(jié)點(diǎn)結(jié)束,然后再開始新一輪的循環(huán)。這種算法簡單,但是沒有考慮到每臺節(jié)點(diǎn)服務(wù)器的具體性能,請求分發(fā)往往不均衡。

代碼實(shí)現(xiàn):

/**
 * 普通輪詢算法
 */public class RoundRobin {
    private static Integer index = 0;
    private static List<String> nodes = new ArrayList<>();
    // 準(zhǔn)備模擬數(shù)據(jù)
    static {
        nodes.add("192.168.1.101");
        nodes.add("192.168.1.103");
        nodes.add("192.168.1.102");
        System.out.println("普通輪詢算法的所有節(jié)點(diǎn):"+nodes);//打印所有節(jié)點(diǎn)
    }
    
    // 關(guān)鍵代碼
    public String selectNode(){
        String ip = null;
        synchronized (index){
            // 下標(biāo)復(fù)位
            if(index>=nodes.size()) index = 0;
            ip = nodes.get(index);
            index++;
        }
        return ip;
    }

    // 并發(fā)測試:兩個(gè)線程循環(huán)獲取節(jié)點(diǎn)
    public static void main(String[] args) {
        new Thread(() -> {
            RoundRobin roundRobin1 = new RoundRobin();
            for (int i=1;i<=5;i++){
                String serverIp = roundRobin1.selectNode();
                System.out.println(Thread.currentThread().getName()+"==第"+i+"次獲取節(jié)點(diǎn):"+serverIp);
            }
        }).start();

        RoundRobin roundRobin2 = new RoundRobin();
        for (int i=1;i<=nodes.size();i++){
            String serverIp = roundRobin2.selectNode();
            System.out.println(Thread.currentThread().getName()+"==第"+i+"次獲取節(jié)點(diǎn):"+serverIp);
        }
    }
}

執(zhí)行結(jié)果:不同線程訪問,結(jié)果依舊是按順序循環(huán)分配節(jié)點(diǎn)

普通輪詢算法的所有節(jié)點(diǎn):[192.168.1.101, 192.168.1.103, 192.168.1.102]

main==第1次獲取節(jié)點(diǎn):192.168.1.101

Thread-0==第1次獲取節(jié)點(diǎn):192.168.1.103

Thread-0==第2次獲取節(jié)點(diǎn):192.168.1.102

Thread-0==第3次獲取節(jié)點(diǎn):192.168.1.101

Thread-0==第4次獲取節(jié)點(diǎn):192.168.1.103

Thread-0==第5次獲取節(jié)點(diǎn):192.168.1.102

main==第2次獲取節(jié)點(diǎn):192.168.1.101

main==第3次獲取節(jié)點(diǎn):192.168.1.103

2.加權(quán)輪詢算法

加權(quán)輪詢(Weighted Round Robin,WRR)是根據(jù)設(shè)定的權(quán)重值來分配訪問請求,權(quán)重值越大的,被分到的請求數(shù)也就越多。一般根據(jù)每臺節(jié)點(diǎn)服務(wù)器的具體性能來分配權(quán)重。

2.1.實(shí)現(xiàn)方式一

將需要輪詢的所有節(jié)點(diǎn)按權(quán)重?cái)?shù)循環(huán)生成一個(gè)List 集合,然后就跟普通輪詢算法一樣,來一個(gè)、分配一個(gè)、進(jìn)1位。

例如:

所有節(jié)點(diǎn)信息:{{“192.168.1.100“,5},{“192.168.1.101“,1},{“192.168.1.102“,3}}

那么生成的List 集合為:

{“192.168.1.100“,

“192.168.1.100“,

“192.168.1.100“,

“192.168.1.100“,

“192.168.1.100“,

“192.168.1.101“,

“192.168.1.102“,

“192.168.1.102“,

“192.168.1.102“}

后面就是普通輪詢算法的邏輯

代碼實(shí)現(xiàn):

類似于二維數(shù)組 降維成 一維數(shù)組,然后使用普通輪詢

/**
 *  簡單版的加權(quán)輪詢
 */public class WeightedRoundRobinSimple {
    private static Integer index = 0;
    private static Map<String,Integer> mapNodes = new HashMap<>();

    // 準(zhǔn)備模擬數(shù)據(jù)
    static {
        mapNodes.put("192.168.1.101",1);
        mapNodes.put("192.168.1.102",3);
        mapNodes.put("192.168.1.103",2);
        /* -- 以下代碼只為了方便查看所有節(jié)點(diǎn),刪除不影響 -- S */
        List<String> nodes = new ArrayList<>();
        Iterator<Map.Entry<String, Integer>> iterator = mapNodes.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Integer> entry = iterator.next();
            String key = entry.getKey();
            for (int i=0;i<entry.getValue();i++){
                nodes.add(key);
            }
        }
        System.out.println("簡單版的加權(quán)輪詢:"+nodes);//打印所有節(jié)點(diǎn)
        /* -- 以上代碼只為了方便查看所有節(jié)點(diǎn),刪除不影響-- E */
    }

    // 關(guān)鍵代碼:類似于二維數(shù)組 降維成 一維數(shù)組,然后使用普通輪詢
    public String selectNode(){
        List<String> nodes = new ArrayList<>();
        Iterator<Map.Entry<String, Integer>> iterator = mapNodes.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Integer> entry = iterator.next();
            String key = entry.getKey();
            for (int i=0;i<entry.getValue();i++){
                nodes.add(key);
            }
        }
        String ip = null;
        synchronized (index){
            // 下標(biāo)復(fù)位
            if(index>=nodes.size()) index = 0;
            ip = nodes.get(index);
            index++;
        }
        return ip;
    }

    // 并發(fā)測試:兩個(gè)線程循環(huán)獲取節(jié)點(diǎn)
    public static void main(String[] args) {
        new Thread(() -> {
            WeightedRoundRobinSimple roundRobin1 = new WeightedRoundRobinSimple();
            for (int i=1;i<=6;i++){
                String serverIp = roundRobin1.selectNode();
                System.out.println(Thread.currentThread().getName()+"==第"+i+"次獲取節(jié)點(diǎn):"+serverIp);
            }
        }).start();

        WeightedRoundRobinSimple roundRobin2 = new WeightedRoundRobinSimple();
        for (int i=1;i<=6;i++){
            String serverIp = roundRobin2.selectNode();
            System.out.println(Thread.currentThread().getName()+"==第"+i+"次獲取節(jié)點(diǎn):"+serverIp);
        }
    }
}

執(zhí)行結(jié)果:兩個(gè)線程循環(huán)測試,輸出結(jié)果會出現(xiàn)交替分配到不同的IP,但最終的效果都是一個(gè)個(gè)按順序分配,類似于普通輪詢算法。

簡單版的加權(quán)輪詢:[192.168.1.103, 192.168.1.103, 192.168.1.101, 192.168.1.102, 192.168.1.102, 192.168.1.102]

main==第1次獲取節(jié)點(diǎn):192.168.1.103

main==第2次獲取節(jié)點(diǎn):192.168.1.103

main==第3次獲取節(jié)點(diǎn):192.168.1.101

main==第4次獲取節(jié)點(diǎn):192.168.1.102

main==第5次獲取節(jié)點(diǎn):192.168.1.102

Thread-0==第1次獲取節(jié)點(diǎn):192.168.1.102

Thread-0==第2次獲取節(jié)點(diǎn):192.168.1.103

main==第6次獲取節(jié)點(diǎn):192.168.1.103

Thread-0==第3次獲取節(jié)點(diǎn):192.168.1.101

Thread-0==第4次獲取節(jié)點(diǎn):192.168.1.102

Thread-0==第5次獲取節(jié)點(diǎn):192.168.1.102

Thread-0==第6次獲取節(jié)點(diǎn):192.168.1.102

2.2.實(shí)現(xiàn)方式二(重點(diǎn)難點(diǎn))

本文的重點(diǎn)難點(diǎn)。

在實(shí)現(xiàn)方式一的算法中可以很明顯的看到,同權(quán)重的IP會被連續(xù)分配,也就是說同一個(gè)IP在短時(shí)間內(nèi)收到不同的請求,過了這個(gè)連續(xù)點(diǎn),就要等到下一輪才會被分配到,并沒有做到均勻分配節(jié)點(diǎn)。

實(shí)現(xiàn)方式二將盡可能地均勻分配每個(gè)節(jié)點(diǎn),節(jié)點(diǎn)分配不再是連續(xù)的,但最終的權(quán)重比和上一個(gè)方式一樣,這種加權(quán)輪詢又被稱為平滑加權(quán)輪詢。

理解關(guān)鍵的幾個(gè)參數(shù)和算法邏輯,方便理解代碼的實(shí)現(xiàn)。

2.2.1.概述

關(guān)鍵參數(shù)

  • ip:負(fù)載IP

  • weight:權(quán)重,保存配置的權(quán)重

  • effectiveWeight:有效權(quán)重,輪詢的過程權(quán)重可能變化

  • currentWeight:當(dāng)前權(quán)重,比對該值大小獲取節(jié)點(diǎn)

注意幾個(gè)點(diǎn):

weight 權(quán)重,在整個(gè)過程不會對它做修改,只用來保存配置時(shí)的權(quán)重參數(shù)值。如果直接拿weight 運(yùn)算而不保存配置的最原始權(quán)重參數(shù),那么將會丟失最關(guān)鍵的用戶配置的權(quán)重參數(shù)。

effectiveWeight 有效權(quán)重,在整個(gè)過程可能會變化,初始值等于weight,主要用于當(dāng)節(jié)點(diǎn)出現(xiàn)分配失敗時(shí)降低權(quán)重值,成功時(shí)提高權(quán)重值(但不能大于weight值),本案例為了簡化算法,并未加入這功能,因此本案例中effectiveWeight始終等于weight。

currentWeight 當(dāng)前權(quán)重,通過循環(huán)所有節(jié)點(diǎn)比對該值大小來分配權(quán)重最大的節(jié)點(diǎn),初始值等于weight。

三個(gè)權(quán)重參數(shù)的變化情況

僅僅針對本案例,因?yàn)楸景咐秊榱撕喕惴?,并未加入[節(jié)點(diǎn)出現(xiàn)分配失敗時(shí)降低權(quán)重值,成功時(shí)提高權(quán)重值(但不能大于weight值)的功能],所以有效權(quán)重effectiveWeight 不會發(fā)生變化。

  • 第一次加權(quán)輪詢時(shí):currentWeight = weight = effectiveWeight;

  • 后面每次加權(quán)輪詢時(shí):currentWeight 的值都會不斷變化,weight 和effectiveWeight 的值不變;

  • 被分配的節(jié)點(diǎn)的currentWeight = currentWeight - 權(quán)重之和

  • 所有節(jié)點(diǎn)的currentWeight = currentWeight + effectiveWeight

2.2.2.舉個(gè)例子理解算法

你面前有三個(gè)瓶子A、B、C,分別裝有1L、3L、2L水。

第一輪分配情況:B多,所以把B瓶子的3L水,分1L給A,分2L給C(按權(quán)重分),分完之后:A、B、C分別為:2L、0L、4L

第二輪分配情況:C多,所以把C瓶子的4L水,分1L給A,分3L給B(按權(quán)重分),分完之后:A、B、C分別為:3L、3L、0L

第三輪分配情況:A和B一樣多,那么拿誰去分呢?拿誰其實(shí)都一樣(算法中寫了A大于B才選A,現(xiàn)在等于,所以不選A),所以把B瓶子的3L水,分1L給A,分2L給C(按權(quán)重分),分完之后:A、B、C分別為:4L、0L、2L

然后不斷的進(jìn)行下去……

簡化成數(shù)學(xué)邏輯(代碼實(shí)現(xiàn))的關(guān)鍵兩步

  • 被分配的節(jié)點(diǎn)的currentWeight = currentWeight - 權(quán)重之和

  • 所有節(jié)點(diǎn)的currentWeight = currentWeight + effectiveWeight

下面通過閱讀代碼來理解

2.2.3.代碼實(shí)現(xiàn)

節(jié)點(diǎn)對象

/**
 * String ip:負(fù)載IP
 * final Integer weight:權(quán)重,保存配置的權(quán)重
 * Integer effectiveWeight:有效權(quán)重,輪詢的過程權(quán)重可能變化
 * Integer currentWeight:當(dāng)前權(quán)重,比對該值大小獲取節(jié)點(diǎn)
 *   第一次加權(quán)輪詢時(shí):currentWeight = weight = effectiveWeight
 *   后面每次加權(quán)輪詢時(shí):currentWeight 的值都會不斷變化,其他權(quán)重不變
 */public class Node implements Comparable<Node>{
    private String ip;
    private final Integer weight;
    private Integer effectiveWeight;
    private Integer currentWeight;

    public Node(String ip,Integer weight){
        this.ip = ip;
        this.weight = weight;
        this.effectiveWeight = weight;
        this.currentWeight = weight;
    }

    public Node(String ip, Integer weight, Integer effectiveWeight, Integer currentWeight) {
        this.ip = ip;
        this.weight = weight;
        this.effectiveWeight = effectiveWeight;
        this.currentWeight = currentWeight;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Integer getWeight() {
        return weight;
    }

    public Integer getEffectiveWeight() {
        return effectiveWeight;
    }

    public void setEffectiveWeight(Integer effectiveWeight) {
        this.effectiveWeight = effectiveWeight;
    }

    public Integer getCurrentWeight() {
        return currentWeight;
    }

    public void setCurrentWeight(Integer currentWeight) {
        this.currentWeight = currentWeight;
    }

    @Override
    public int compareTo(Node node) {
        return currentWeight > node.currentWeight ? 1 : (currentWeight.equals(node.currentWeight) ? 0 : -1);
    }

    @Override
    public String toString() {
        return "{ip='" + ip + "', weight=" + weight + ", effectiveWeight=" + effectiveWeight + ", currentWeight=" + currentWeight + "}";
    }
}

加權(quán)輪詢算法

/**
 * 加權(quán)輪詢算法
 */public class WeightedRoundRobin {

    private static List<Node> nodes = new ArrayList<>();
    // 權(quán)重之和
    private static Integer totalWeight = 0;
    // 準(zhǔn)備模擬數(shù)據(jù)
    static {
        nodes.add(new Node("192.168.1.101",1));
        nodes.add(new Node("192.168.1.102",3));
        nodes.add(new Node("192.168.1.103",2));
        nodes.forEach(node -> totalWeight += node.getEffectiveWeight());
    }

    /**
     * 按照當(dāng)前權(quán)重(currentWeight)最大值獲取IP
     * @return Node
     */
    public Node selectNode(){
        if (nodes ==null || nodes.size()<=0) return null;
        if (nodes.size() == 1)  return nodes.get(0);

        Node nodeOfMaxWeight = null; // 保存輪詢選中的節(jié)點(diǎn)信息
        synchronized (nodes){
            // 打印信息對象:避免并發(fā)時(shí)打印出來的信息太亂,不利于觀看結(jié)果
            StringBuffer sb = new StringBuffer();
            sb.append(Thread.currentThread().getName()+"==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:"+printCurrentWeight(nodes));

            // 選出當(dāng)前權(quán)重最大的節(jié)點(diǎn)
            Node tempNodeOfMaxWeight = null;
            for (Node node : nodes) {
                if (tempNodeOfMaxWeight == null)
                    tempNodeOfMaxWeight = node;
                else
                    tempNodeOfMaxWeight = tempNodeOfMaxWeight.compareTo(node) > 0 ? tempNodeOfMaxWeight : node;
            }
            // 必須new個(gè)新的節(jié)點(diǎn)實(shí)例來保存信息,否則引用指向同一個(gè)堆實(shí)例,后面的set操作將會修改節(jié)點(diǎn)信息
            nodeOfMaxWeight = new Node(tempNodeOfMaxWeight.getIp(),tempNodeOfMaxWeight.getWeight(),tempNodeOfMaxWeight.getEffectiveWeight(),tempNodeOfMaxWeight.getCurrentWeight());

            // 調(diào)整當(dāng)前權(quán)重比:按權(quán)重(effectiveWeight)的比例進(jìn)行調(diào)整,確保請求分發(fā)合理。
            tempNodeOfMaxWeight.setCurrentWeight(tempNodeOfMaxWeight.getCurrentWeight() - totalWeight);
            sb.append(" -> "+printCurrentWeight(nodes));

            nodes.forEach(node -> node.setCurrentWeight(node.getCurrentWeight()+node.getEffectiveWeight()));

            sb.append(" -> "+printCurrentWeight(nodes));
            System.out.println(sb); //打印權(quán)重變化過程
        }
        return nodeOfMaxWeight;
    }

    // 格式化打印信息
    private String printCurrentWeight(List<Node> nodes){
        StringBuffer stringBuffer = new StringBuffer("[");
        nodes.forEach(node -> stringBuffer.append(node.getCurrentWeight()+",") );
        return stringBuffer.substring(0, stringBuffer.length() - 1) + "]";
    }

    // 并發(fā)測試:兩個(gè)線程循環(huán)獲取節(jié)點(diǎn)
    public static void main(String[] args){
        Thread thread = new Thread(() -> {
            WeightedRoundRobin weightedRoundRobin1 = new WeightedRoundRobin();
            for(int i=1;i<=totalWeight;i++){
                Node node = weightedRoundRobin1.selectNode();
                System.out.println(Thread.currentThread().getName()+"==第"+i+"次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):" + node + "\n");
            }
        });
        thread.start();
        //
        WeightedRoundRobin weightedRoundRobin2 = new WeightedRoundRobin();
        for(int i=1;i<=totalWeight;i++){
            Node node = weightedRoundRobin2.selectNode();
            System.out.println(Thread.currentThread().getName()+"==第"+i+"次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):" + node + "\n");
        }

    }
}

執(zhí)行結(jié)果:

main==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[1,3,2] -> [1,-3,2] -> [2,0,4] main==第1次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.102', weight=3, effectiveWeight=3, currentWeight=3}

Thread-0==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[2,0,4] -> [2,0,-2] -> [3,3,0] Thread-0==第1次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.103', weight=2, effectiveWeight=2, currentWeight=4}

main==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[3,3,0] -> [3,-3,0] -> [4,0,2] main==第2次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.102', weight=3, effectiveWeight=3, currentWeight=3}

main==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[4,0,2] -> [-2,0,2] -> [-1,3,4] main==第3次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.101', weight=1, effectiveWeight=1, currentWeight=4}

Thread-0==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[-1,3,4] -> [-1,3,-2] -> [0,6,0] Thread-0==第2次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.103', weight=2, effectiveWeight=2, currentWeight=4}

main==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[0,6,0] -> [0,0,0] -> [1,3,2] main==第4次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.102', weight=3, effectiveWeight=3, currentWeight=6}

Thread-0==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[1,3,2] -> [1,-3,2] -> [2,0,4] Thread-0==第3次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.102', weight=3, effectiveWeight=3, currentWeight=3}

main==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[2,0,4] -> [2,0,-2] -> [3,3,0] main==第5次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.103', weight=2, effectiveWeight=2, currentWeight=4}

Thread-0==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[3,3,0] -> [3,-3,0] -> [4,0,2] Thread-0==第4次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.102', weight=3, effectiveWeight=3, currentWeight=3}

main==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[4,0,2] -> [-2,0,2] -> [-1,3,4] main==第6次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.101', weight=1, effectiveWeight=1, currentWeight=4}

Thread-0==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[-1,3,4] -> [-1,3,-2] -> [0,6,0] Thread-0==第5次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.103', weight=2, effectiveWeight=2, currentWeight=4}

Thread-0==加權(quán)輪詢--[當(dāng)前權(quán)重]值的變化:[0,6,0] -> [0,0,0] -> [1,3,2] Thread-0==第6次輪詢選中[當(dāng)前權(quán)重最大]的節(jié)點(diǎn):{ip='192.168.1.102', weight=3, effectiveWeight=3, currentWeight=6}

為了方便分析,簡化兩線程執(zhí)行后的結(jié)果

[當(dāng)前權(quán)重]值的變化:[1,3,2] -> [1,-3,2] -> [2,0,4]

[當(dāng)前權(quán)重]值的變化:[2,0,4] -> [2,0,-2] -> [3,3,0]

[當(dāng)前權(quán)重]值的變化:[3,3,0] -> [3,-3,0] -> [4,0,2]

[當(dāng)前權(quán)重]值的變化:[4,0,2] -> [-2,0,2] -> [-1,3,4]

[當(dāng)前權(quán)重]值的變化:[-1,3,4] -> [-1,3,-2] -> [0,6,0]

[當(dāng)前權(quán)重]值的變化:[0,6,0] -> [0,0,0] -> [1,3,2]

[當(dāng)前權(quán)重]值的變化:[1,3,2] -> [1,-3,2] -> [2,0,4]

[當(dāng)前權(quán)重]值的變化:[2,0,4] -> [2,0,-2] -> [3,3,0]

[當(dāng)前權(quán)重]值的變化:[3,3,0] -> [3,-3,0] -> [4,0,2]

[當(dāng)前權(quán)重]值的變化:[4,0,2] -> [-2,0,2] -> [-1,3,4]

[當(dāng)前權(quán)重]值的變化:[-1,3,4] -> [-1,3,-2] -> [0,6,0]

[當(dāng)前權(quán)重]值的變化:[0,6,0] -> [0,0,0] -> [1,3,2]

因?yàn)檎麄€(gè)過程只有當(dāng)前權(quán)重發(fā)生變化,所以分析清楚它就明白了整個(gè)過程。

結(jié)論:

分配完成后當(dāng)前權(quán)重發(fā)生變化,但權(quán)限之和還是等于最初值;

每6輪(1+3+2權(quán)重)就出現(xiàn)權(quán)重全部為0,所以會出現(xiàn)重新循環(huán),6正好等于權(quán)重之和,權(quán)重比等于1/6 : 3/6 : 2/6;

a=權(quán)重1,b=權(quán)重3,c=權(quán)重2,那么權(quán)重變化的6(a+b+c)次中,分配情況為:b c b a c b,很明顯,每個(gè)節(jié)點(diǎn)均勻按權(quán)重分配,節(jié)點(diǎn)分配不再是連續(xù)的。這也是最重要的結(jié)論,正是實(shí)現(xiàn)方式二在文初提到的要實(shí)現(xiàn)的關(guān)鍵點(diǎn)。

該算法在權(quán)重比相差很大時(shí),比如:A=1,B=5,那這個(gè)算法的結(jié)果就跟方式一沒啥區(qū)別了,分配結(jié)果就變成了:{A,B,B,B,B,B},既然沒區(qū)別,那根據(jù)算法復(fù)雜情況,那肯定方式一更好了,所以方式一和方式二可以互補(bǔ),可以根據(jù)權(quán)重比選擇不同的算法。

留下懸念

第一點(diǎn):節(jié)點(diǎn)出現(xiàn)分配失敗時(shí)降低有效權(quán)重值,成功時(shí)提高有效權(quán)重值(但不能大于weight值)的功能。理解了方式二,后面再加這塊功能進(jìn)去就很好理解了;

第二點(diǎn):該算法實(shí)現(xiàn)的背后數(shù)學(xué)證明,用的是什么數(shù)學(xué)理論?

總結(jié)

到此這篇關(guān)于Java負(fù)載均衡算法實(shí)現(xiàn)之輪詢和加權(quán)輪詢的文章就介紹到這了,更多相關(guān)Java輪詢和加權(quán)輪詢算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論