zoukankan      html  css  js  c++  java
  • 负载均衡算法

    转自;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());
        }

    最小压力算法

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

  • 相关阅读:
    随笔2
    随笔
    关于updateElement接口
    随笔1
    本地访问正常,服务器访问乱码 记录
    Redis (error) NOAUTH Authentication required.解决方法
    tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
    微信公众号消息回复
    微信公众号 报token验证失败
    idea中web.xml报错 Servlet should have a mapping
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/10578883.html
Copyright © 2011-2022 走看看