• 负载均衡算法-java实现


    出处:  Java代码实现负载均衡五种算法

    前言: 

         负载均衡是为了解决并发情况下,多个请求访问,把请求通过提前约定好的规则转发给各个server。其中有好几个种经典的算法。在用java代码编写这几种算法之前,先来了解一下负载均衡这个概念。

    1.概念

        负载,从字面意思可以分析,是指后端server可以承受的压力。这个一方面是服务器的性能,另一方面就是代码的质量了。

        均衡,就是说把服务部署在多态server,如何调度这些资源。根据服务器性能不同,进行一个权衡。

        当web访问量增加,服务器性能不同,更好的去利用服务器,我们需要负载均衡算法。

    2.几种负载均衡算法简介

    主要的负载均衡算法是图中这些,在代码实现之前,我们先简单回顾一下他们的概念。

    轮询法:

       轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器。

       优点:绝对公平

       缺点:无法根据服务器性能去分配,无法合理利用服务器资源。

    加权轮询法:

        该算法中,每个机器接受的连接数量是按权重比例分配的。这是对普通轮询算法的改进,比如你可以设定:第三台机器的处理能力是第一台机器的两倍,那么负载均衡器会把两倍的连接数量分配给第3台机器。加权轮询分为:简单的轮询、平滑的轮询。

         什么是平滑的轮询,就是把每个不同的服务,平均分布。在Nginx源码中,实现了一种叫做平滑的加权轮询(smooth weighted round-robin balancing)的算法,它生成的序列更加均匀。5个请求现在分散开来,不再是连续的。

    随机法:

        负载均衡方法随机的把负载分配到各个可用的服务器上,通过随机数生成算法选取一个服务器。毕竟随机,,有效性受到了质疑。

    加权随机法:

         获取带有权重的随机数字,随机这种东西,不能看绝对,只能看相对。

    IP_Hash算法:

        hash(object)%N算法,通过一种散列算法把请求分配到不同的服务器上。

    3.Java代码实现负载均衡五种算法

        1.轮询法:

    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
     
    public class TestRoundRobin { 
        // 1.定义map, key-ip,value-weight
        static Map<String,Integer> ipMap=new HashMap<>();
        static {
            ipMap.put("192.168.13.1",1);
            ipMap.put("192.168.13.2",1);
            ipMap.put("192.168.13.3",1);
     
        }
     
      // Integer sum=0;
        Integer  pos = 0;
     
        public String RoundRobin(){
            Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
            ipServerMap.putAll(ipMap);
     
            // 2.取出来key,放到set中
            Set<String> ipset=ipServerMap.keySet();
     
            // 3.set放到list,要循环list取出
            ArrayList<String> iplist=new ArrayList<String>();
            iplist.addAll(ipset);
     
            String serverName=null;
     
            // 4.定义一个循环的值,如果大于set就从0开始
            synchronized(pos){
                if (pos>=ipset.size()){
                    pos=0;
                }
                serverName=iplist.get(pos);
                //轮询+1
                pos ++;
            }
            return serverName;
     
        }
     
        public static void main(String[] args) {
            TestRoundRobin testRoundRobin=new TestRoundRobin();
            for (int i=0;i<10;i++){
                String serverIp=testRoundRobin.RoundRobin();
                System.out.println(serverIp);
            }
        }
     
    }

    2.加权轮询法

    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
     
    public class TestWeightRobin {
        //    1.map, key-ip,value-weight
        static Map<String,Integer> ipMap=new HashMap<>();
        static {
            ipMap.put("192.168.13.1",1);
            ipMap.put("192.168.13.2",2);
            ipMap.put("192.168.13.3",4);
     
        }
        Integer pos=0;
        public String WeightRobin(){
            Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
            ipServerMap.putAll(ipMap);
     
            Set<String> ipSet=ipServerMap.keySet();
            Iterator<String> ipIterator=ipSet.iterator();
     
            //定义一个list放所有server
            ArrayList<String> ipArrayList=new ArrayList<String>();
     
            //循环set,根据set中的可以去得知map中的value,给list中添加对应数字的server数量
            while (ipIterator.hasNext()){
                String serverName=ipIterator.next();
                Integer weight=ipServerMap.get(serverName);
                for (int i = 0;i < weight ;i++){
                    ipArrayList.add(serverName);
                }
            }
            String serverName=null;
            if (pos>=ipArrayList.size()){
                pos=0;
            }
            serverName=ipArrayList.get(pos);
            //轮询+1
            pos ++;
     
            return  serverName;
        }
     
        public static void main(String[] args) {
            TestWeightRobin testWeightRobin=new TestWeightRobin();
            for (int i =0;i<10;i++){
                String server=testWeightRobin.WeightRobin();
                System.out.println(server);
            }
     
        }
    }

    3.随机法:

    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class TestRandom {
        //    1.定义map, key-ip,value-weight
        static Map<String,Integer> ipMap=new HashMap<>();
        static {
            ipMap.put("192.168.13.1",1);
            ipMap.put("192.168.13.2",2);
            ipMap.put("192.168.13.3",4);
     
        }
        public String Random() {
            Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
            ipServerMap.putAll(ipMap);
     
            Set<String> ipSet=ipServerMap.keySet();
     
            //定义一个list放所有server
            ArrayList<String> ipArrayList=new ArrayList<String>();
            ipArrayList.addAll(ipSet);
     
            //循环随机数
            Random random=new Random();
            //随机数在list数量中取(1-list.size)
            int pos=random.nextInt(ipArrayList.size());
            String serverNameReturn= ipArrayList.get(pos);
            return  serverNameReturn;
        }
     
        public static void main(String[] args) {
            TestRandom testRandom=new TestRandom();
            for (int i =0;i<10;i++){
                String server=testRandom.Random();
                System.out.println(server);
            }
     
        }
    }

    4.加权随机:

    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class TestRobinRandom {
     
        //    1.定义map, key-ip,value-weight
        static Map<String,Integer> ipMap=new HashMap<>();
        static {
            ipMap.put("192.168.13.1",1);
            ipMap.put("192.168.13.2",2);
            ipMap.put("192.168.13.3",4);
     
        }
        public String RobinRandom(){
            Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
            ipServerMap.putAll(ipMap);
     
            Set<String> ipSet=ipServerMap.keySet();
            Iterator<String> ipIterator=ipSet.iterator();
     
            //定义一个list放所有server
            ArrayList<String> ipArrayList=new ArrayList<String>();
     
            //循环set,根据set中的可以去得知map中的value,给list中添加对应数字的server数量
            while (ipIterator.hasNext()){
                String serverName=ipIterator.next();
                Integer weight=ipServerMap.get(serverName);
                for (int i=0;i<weight;i++){
                    ipArrayList.add(serverName);
                }
            }
     
            //循环随机数
            Random random=new Random();
            //随机数在list数量中取(1-list.size)
            int pos=random.nextInt(ipArrayList.size());
            String serverNameReturn= ipArrayList.get(pos);
            return  serverNameReturn;
        }
     
        public static void main(String[] args) {
            TestRobinRandom testRobinRandom=new TestRobinRandom();
            for (int i =0;i<10;i++){
                String server=testRobinRandom.RobinRandom();
                System.out.println(server);
            }
     
        }
    }

    5.IP_Hash算法:

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.ConcurrentHashMap;
     
    public class ipHash {
        //    1.定义map, key-ip,value-weight
        static Map<String,Integer> ipMap=new HashMap<>();
        static {
            ipMap.put("192.168.13.1",1);
            ipMap.put("192.168.13.2",2);
            ipMap.put("192.168.13.3",4);
        }
        public String ipHash(String clientIP){
            Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
            ipServerMap.putAll(ipMap);
     
            //    2.取出来key,放到set中
            Set<String> ipset=ipServerMap.keySet();
     
            //    3.set放到list,要循环list取出
            ArrayList<String> iplist=new ArrayList<String>();
            iplist.addAll(ipset);
     
            //对ip的hashcode值取余数,每次都一样的
            int hashCode=clientIP.hashCode();
            int serverListsize=iplist.size();
            int pos=hashCode%serverListsize;
            return iplist.get(pos);
     
        }
     
        public static void main(String[] args) {
            ipHash iphash=new ipHash();
            String servername= iphash.ipHash("192.168.21.2");
            System.out.println(servername);
        }
     
    }
  • 相关阅读:
    js实现的hashMap
    vi编辑器常用命令汇总以及linux系统操作的命令(自己需要用到什么,经过测试正确的,会持续向上添加)
    使用conda,提示-bash: conda: command not found
    tmux常用命令
    OSError: [WinError 126] JVM DLL not found: C:Program FilesJavajdk1.8.0_131jreinserverjvm.dll
    python建立连接,获取动态地址,有缺陷
    python代码中,添加子进程的运行
    python通过建立长链接,获取动态ip,这种方式可以长时间保持连接
    ImportError: cannot import name PDFDocument
    http请求参数之Query String Parameters、Form Data、Request Payload
  • 原文地址:https://www.cnblogs.com/myseries/p/12670083.html
Copyright © 2020-2023  润新知