负载均衡算法

转自;https://www.xttblog.com/?p=4012

1.常见的负载均衡算法有7种:

1.完全随机算法

2.加权随机算法

3.完全轮询(Round Robin)算法

4.加权轮询算法

5.平滑加权轮询算法

6.哈希算法

7.最小压力算法

完全随机算法:

实现原理:随机从负载中获取一台机器。

    // 完全随机算法
    public String absoluteRandom() {
        // 服务器列表
        List<String> serverList = new ArrayList<>();
        serverList.add("server1");
        serverList.add("server2");
        serverList.add("server3");
        Random random = new Random();
        int randomNum = random.nextInt(serverList.size());
        String selectServer = serverList.get(randomNum);
        return selectServer;
    }

加权随机算法:

实现原理:根据配置的权重大小,往服务器列表中存入的当前服务器的数量等于权重多少,再根据列表总数生成随机数取执行的服务器。

// 加权随机算法
    public String weightRandom() {
        Map<String, Integer> serverMap = new HashMap<>(4);
        serverMap.put("sever1", 3);
        serverMap.put("server2", 5);
        serverMap.put("server3", 2);
        Set<Map.Entry<String, Integer>> me = serverMap.entrySet();
        List<String> serverList = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : me) {
            // 遍历权重大小往服务器列表中塞值
            for (int i = 0; i < entry.getValue(); i++) {
                serverList.add(entry.getKey());
            }
        }
        Random random = new Random();
        int randomNum = random.nextInt(serverList.size());
        return serverList.get(randomNum);
    }

完全轮询算法:

实现原理:按顺序依次接收请求

// 完全轮询算法
    int index = 0;
    public String absolutePoll() {
        // 服务器列表
        List<String> serverList = new ArrayList<>();
        serverList.add("server1");
        serverList.add("server2");
        serverList.add("server3");
        if (index == serverList.size()) {
            index = 0;
        }
        return serverList.get(index++);
    }

加权轮询算法:

    // 加权轮询算法
    int index = 0;
    public String weightPoll() {
        Map<String, Integer> serverMap = new HashMap<>(4);
        serverMap.put("sever1", 3);
        serverMap.put("server2", 5);
        serverMap.put("server3", 2);
        Set<Map.Entry<String, Integer>> me = serverMap.entrySet();
        List<String> serverList = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : me) {
            // 遍历权重大小往服务器列表中塞值
            for (int i = 0; i < entry.getValue(); i++) {
                serverList.add(entry.getKey());
            }
        }
        if (index == serverList.size()) {
            index = 0;
        }
        return serverList.get(index++);
    }

平滑加权轮询算法:

加权轮询可能在实际中会出现某个服务器权重大,导致长时间执行,一旦遇到耗时大的请求,压力非常的大,存在着不合理性,因此又有了平滑加权轮询算法。

 平滑加权算法不仅使权重配置高的服务器轮询的次数多,而且不会使多个请求一直轮询到同一个此服务器上。

假设有n太服务器,S={S1,S2,...,Sn},配置权重W={W1,W2,...,Wn},有效权重CW={CW1,CW2,...,CWn}。每个服务器除了存在一个配置权重外还有一个当前的有效权重CWi,且CWi的初始值等于Wi;

currentServer表示当前选中的服务器,初始值为-1,所有服务器的配置权重和为allWeightSum。

步骤:

1、初始每个服务器i的当前有效权重CWi为配置权重Wi,并求得配置权重和allWeightSum;

2、选出当前有效权重最大的服务器,那么currentServer的值指向它,将当前有效权重CWi减去所有服务器的配置权重和allWeightSum

3、将每台服务器i的当前有效权重CWi都加上配置权重Wi

4、取到变量currentServer指向的服务器

5、每次轮询循环2,3,4步骤

private static Map<String, SmoothWeightServer> serverMap = new HashMap<>();

    /**
     * 所有服务器的配置权重和
     */
    static int allWeightSum;

    static {
        serverMap.put("server1", new SmoothWeightServer(5, 5, "server1"));
        serverMap.put("server2", new SmoothWeightServer(1, 1, "server2"));
        serverMap.put("server3", new SmoothWeightServer(2, 2, "server3"));
//        for (Map.Entry<String, SmoothWeightServer> entry : serverMap.entrySet()) {
//            SmoothWeightServer currentServer = entry.getValue();
//            // 配置权重值之和
//            allWeightSum += currentServer.getWeight();
//        }
        allWeightSum = 8;
    }


    /**
     * 平滑加权轮询
     *
     * @return
     */
    public static String smoothPoll() {
        SmoothWeightServer maxWeightServer = null;
        for (Map.Entry<String, SmoothWeightServer> entry : serverMap.entrySet()) {
            SmoothWeightServer currentServer = entry.getValue();
            // 配置权重值只获取一次即可
            if (maxWeightServer == null || currentServer.getCurrentWeight() > maxWeightServer.getCurrentWeight()) {
                maxWeightServer = currentServer;
            }
        }
        // 将当前选中的服务器的当前有效权重值减去总配置权重值,将每台服务器加上当前服务器的配置权重
        maxWeightServer.setCurrentWeight(maxWeightServer.getCurrentWeight() - allWeightSum);
        for (Map.Entry<String, SmoothWeightServer> entry : serverMap.entrySet()) {
            SmoothWeightServer currentServer = entry.getValue();
            currentServer.setCurrentWeight(currentServer.getCurrentWeight() + currentServer.getWeight());
        }
        return maxWeightServer.getIp();
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(smoothPoll());
        }
    }

哈希负载均衡算法

实现原理:在集群环境下,让同一个用户的访问,分流到同一台服务器上。根据客户端的ip地址通过哈希运算得到一个哈希值,将此哈希值和服务器的总数取模,得到的值就是选择的服务器的下标

    public String hashPoll(String clientIp) {
        // 服务器列表
        List<String> serverList = new ArrayList<>();
        serverList.add("server1");
        serverList.add("server2");
        serverList.add("server3");

        int hashCode = clientIp.hashCode();
        return serverList.get(hashCode % serverList.size());
    }

最小压力算法

动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能的提高后台服务器利用率,将负载合理的分流到每一台服务器

原文地址:https://www.cnblogs.com/yangyongjie/p/10578883.html