新闻资讯

新闻资讯 行业动态

Java 实现6种负载均衡算法

编辑:006     时间:2020-03-13

1、完全随机算法

缺点:所有服务器的访问概率都是相同的。

package com.example.demo.core.random;

 

import java.util.Arrays;

import java.util.List;

import java.util.Random;

 

/**

 * 负载均衡算法

 * 完全随机算法

 */

public class RandomServer {

 

    public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");

 

    static Random random = new Random();

 

    public static String getServer() {

        int number = random.nextInt(list.size());

        return list.get(number);

    }

 

    public static void main(String[] args) {

        for(int i = 0; i < 15; i++) {

            System.out.println(getServer());

        }

    }

}

2、加权随机算法

场景:有的服务器性能高,可以让随机到此服务器的可能性增大


在这里小编建了一个前端学习交流扣扣群:132667127,我自己整理的最新的前端资料和高级开发教程,如果有想需要的,可以加群一起学习交流

缺点:权重低的服务器可能很长一段时间都访问不到3

package com.example.demo.core.random;

 

import java.util.*;

 

/**

 * 负载均衡算法

 *

 * 如果某一台服务器性能比较高,设置访问的权重高一点

 *

 * 加权随机算法

 */

public class WeightRandomServer {

 

    public static Map<String,Integer> map = new HashMap<>();

 

    static {

        map.put("10.180.11.126:8888",2);

        map.put("10.180.11.128:8888",7);

        map.put("10.180.11.130:8888",1);

    }

 

    static Random random = new Random();

 

    /**

     * 当权重设置过大时,list容易被撑爆

     * @return

     */

    public static String getServer() {

 

        List<String> list = new ArrayList<>();

 

        for(Map.Entry<String,Integer> entry: map.entrySet()) {

 

            //根据权重,决定向list中添加几次

            for(int i = 0; i < entry.getValue(); i++) {

 

                list.add(entry.getKey());

            }

        }

        //list的大小

        int weight = map.values().stream().mapToInt(p -> p).sum();

 

        int number = random.nextInt(weight);

 

        return list.get(number);

    }

 

 

    /**

     * 优化后

     * @return

     */

    public static String getServer1() {

        //计算总权值

        int weight = map.values().stream().mapToInt(p -> p).sum();

 

        //随机一个随机数

        int index = random.nextInt(weight);

 

        //遍历  服务  map

        for(Map.Entry<String,Integer> entry : map.entrySet()) {

            //如果权重大于  索引

            if(entry.getValue() >= index) {

                // 返回这个服务

                return entry.getKey();

            }

            //否则,索引 = 当前索引 - 当前服务的权重

            index = index - entry.getValue();

        }

        return "";

    }

 

    public static void main(String[] args) {

 

        for(int i = 0; i < 15; i++) {

 

            //System.out.println(getServer());

            System.out.println(getServer1());

        }

    }

}

3、完全轮询算法

缺点:从头到尾轮询一遍,不能根据服务器性能设置权重

package com.example.demo.core.poll;

 

import java.util.Arrays;

import java.util.List;

 

/**

 * 完全轮询算法

 */

public class PollServer {

    public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");

 

    static int index;

 

    public static String getServer() {

        if(index == list.size()) {

            index = 0;

        }

        return list.get(index++);

    }

 

    public static void main(String[] args) {

 

        for(int i = 0; i < 15; i++) {

 

            System.out.println(getServer());

        }

    }

}

4、加权轮询算法

有点:可以根据服务器性能设置访问权重

缺点:可能某个服务器权重大,长时间执行,遇到耗时大的请求,压力会很大

package com.example.demo.core.poll;

 

import java.util.HashMap;

import java.util.Map;

 

/**

 * 加权轮询算法

 * 实际中可能遇到某个服务器压力较大,长时间执行。

 */

public class WeightPollServer {

 

    public static Map<String,Integer> map = new HashMap<>();

 

    static {

        map.put("10.180.11.126:8888",2);

        map.put("10.180.11.128:8888",7);

        map.put("10.180.11.130:8888",5);

    }

 

    static int index;

 

    public static String getServer() {

        int weight = map.values().stream().mapToInt( p -> p).sum();

        int number = (index++) % weight;

        for(Map.Entry<String,Integer> entry : map.entrySet()) {

            if(entry.getValue() >= number) {

                return entry.getKey();

            }

            number = number - entry.getValue();

        }

        return "";

    }

 

    public static void main(String[] args) {

 

        for(int i = 0; i < 15; i++) {

            System.out.println(getServer());

        }

    }

}

5、平滑加权轮询算法

优点:根据权重分配服务,同时又保证权重低的服务可以被访问到

缺点:集群环境下,同一个用户访问无法分流到固定一台机器

package com.example.demo.core.smooth;

 

/**

 * 平滑加权

 */

public class SmoothWeight {

 

    private int weight;

 

    private int currentWeight;

 

    private String address;

 

 

    public int getWeight() {

        return weight;

    }

 

    public void setWeight(int weight) {

        this.weight = weight;

    }

 

    public int getCurrentWeight() {

        return currentWeight;

    }

 

    public void setCurrentWeight(int currentWeight) {

        this.currentWeight = currentWeight;

    }

 

    public String getAddress() {

        return address;

    }

 

    public void setAddress(String address) {

        this.address = address;

    }

 

    public SmoothWeight(int weight, int currentWeight, String address) {

        this.weight = weight;

        this.currentWeight = currentWeight;

        this.address = address;

    }

}
package com.example.demo.core.smooth;

 

import java.util.HashMap;

import java.util.Map;

 

/**

 * 平滑加权轮询算法

 */

public class SmoothWeightPollServer {

 

 

    public static Map<String,SmoothWeight> map = new HashMap<>();

 

    static {

        map.put("10.180.11.126:8888",new SmoothWeight(5,5,"10.180.11.126:8888"));

        map.put("10.180.11.128:8888",new SmoothWeight(2,2,"10.180.11.128:8888"));

        map.put("10.180.11.130:8888",new SmoothWeight(4,4,"10.180.11.130:8888"));

    }

 

    public static String getServer() {

 

        SmoothWeight maxSmoothWeight = null;

 

        int weight = map.values().stream().mapToInt(SmoothWeight :: getWeight).sum();

 

        for(Map.Entry<String,SmoothWeight> entry : map.entrySet()) {

 

            SmoothWeight currentSmoothWeight = entry.getValue();

 

            if(maxSmoothWeight == null || currentSmoothWeight.getCurrentWeight() > maxSmoothWeight.getCurrentWeight()) {

                maxSmoothWeight = currentSmoothWeight;

            }

        }

        assert maxSmoothWeight != null;

        maxSmoothWeight.setCurrentWeight(maxSmoothWeight.getCurrentWeight() - weight);

        for(Map.Entry<String,SmoothWeight> entry : map.entrySet()) {

 

            SmoothWeight currentSmoothWeight = entry.getValue();

 

            currentSmoothWeight.setCurrentWeight(currentSmoothWeight.getCurrentWeight() + currentSmoothWeight.getWeight());

        }

 

        return maxSmoothWeight.getAddress();

    }

 

 

    public static void main(String[] args) {

 

        for(int i = 0; i < 15; i++) {

            System.out.println(getServer());

        }

    }

}

6、哈希负载算法

package com.example.demo.core.hash;

 

import java.util.Arrays;

import java.util.List;

import java.util.SortedMap;

import java.util.TreeMap;

 

/**

 * hash负载算法

 * 在一个集群环境下,让同一个用户的访问,分流到固定的一台机器上

 */

public class HashServer {

 

    public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");

 

    public static String getServer(String client){

        int nodeCount = 40;

 

        TreeMap<Integer,String> treeMap = new TreeMap<>();

 

        for(String s : list) {

            for(int i = 0; i < nodeCount; i++) {

                treeMap.put((s + "address:" + i).hashCode(), s);

            }

        }

 

        SortedMap<Integer,String> sortedMap = treeMap.tailMap(client.hashCode());

 

        Integer firstHash = (sortedMap.size() > 0) ? sortedMap.firstKey() : treeMap.firstKey();

 

        return treeMap.get(firstHash);

    }

 

    public static void main(String[] args) {

 

        for(int i = 0; i < 100; i++) {

            System.out.println(getServer("用户:" + i + "访问"));

        }

    }

 

}


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69940844/viewspace-2678820/,如需转载,请注明出处,否则将追究法律责任。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐