負載均衡算法思想

1)輪訓(Round Robin)法
此算法將請求按順序輪流的分配到後端服務器,他均衡的對待後臺每一臺服務器,而不關心服務器實際的連接數和當前的系統負載

public class RoundRobin {
    private static Map<String,Integer> serverWeightMap=new HashMap<String,Integer>();
    private static volatile Integer pos=new Integer(0);
    static{
        serverWeightMap.put("192.168.1.100",1);
        serverWeightMap.put("192.168.1.101",1);
        serverWeightMap.put("192.168.1.102",4);

        serverWeightMap.put("192.168.1.103",1);
        serverWeightMap.put("192.168.1.104",1);
        serverWeightMap.put("192.168.1.105",3);
        serverWeightMap.put("192.168.1.106",1);

        serverWeightMap.put("192.168.1.107",2);
        serverWeightMap.put("192.168.1.108",1);
        serverWeightMap.put("192.168.1.109",1);
        serverWeightMap.put("192.168.1.110",1);

    }

    public static void main(String[] args) {
        for(int i=0;i<100;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(testRoundRobin());
                }
            }).start();
        }

    }

    public static String testRoundRobin(){
        //重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
        Map<String,Integer> serverMap=
              new HashMap<String,Integer>();
        serverMap.putAll(serverWeightMap);
        //取得Ip地址list
        Set<String> keySet=serverMap.keySet();
        ArrayList<String> keyList=new ArrayList<String>();
        keyList.addAll(keySet);

        String server=null;

        synchronized(pos){
            if(pos>=keySet.size()){
                pos=0;
            }
            server=keyList.get(pos); 
            pos++;
        }
        return server;
    }

}

2)隨機(Random)法
通過系統隨機函數,根據後端服務器列表的大小值來隨機選取其中一臺進行訪問。由概率統計論得知,隨着調用量的增大,其實際效果越來越接近平均分配流浪到每一臺後端服務器。

    public static String testRandom(){
        //重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
        Map<String,Integer> serverMap=
            new HashMap<String,Integer>();
        serverMap.putAll(serverWeightMap);
        //取得Ip地址list
        Set<String> keySet=serverMap.keySet();
        ArrayList<String> keyList=new ArrayList<String>();
        keyList.addAll(keySet);

        int randomPos = new Random().nextInt(keyList.size());
        return keyList.get(randomPos);
    }

3)源地址哈希(Hash)法
源地址哈希法的思想是獲取客戶端訪問的IP地址,通過哈希函數計算得到一個數值,用該數值對服務器列表的大小進行取模運算,得到的結果便是要訪問的服務器的序號。採用哈希法進行負載均衡,當後端服務器列表不變時,同一IP地址的客戶端,每次都會被影射到同一臺後端服務器。

public static String testConsumerHash(String remoteip){
            //重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
            Map<String,Integer> serverMap=
                    new HashMap<String,Integer>();
            serverMap.putAll(serverWeightMap);
            //取得Ip地址list
            Set<String> keySet=serverMap.keySet();
            ArrayList<String> keyList=new ArrayList<String>();
            keyList.addAll(keySet);
            int hashCode=remoteip.hashCode();
            int size=keyList.size();
            int serverPos=hashCode%size;
            //此處服務器key是其Ip哈希值(hashCode%size)
            return keyList.get(serverPos);
    }

4)加權輪詢法
不同的後端服務器可能機器的配置和當前系統的負載並不相同,因此它們的抗壓能力也不盡相同。給配置高的、負載低的機器更高的權重,讓其處理更多請求,而低配置、負載高的機器,則給其分配較低的權重,降低其系統負載。

    public static String testWeightRoundRobin(){
        //重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
        Map<String,Integer> serverMap=
            new HashMap<String,Integer>();
        serverMap.putAll(serverWeightMap);
        //取得Ip地址list
        Set<String> keySet=serverMap.keySet();
        Iterator<String> it=keySet.iterator();

        ArrayList<String> serverList=new ArrayList<String>();

        while(it.hasNext()){
            String server=it.next();
            Integer weight=serverMap.get(server);
            for(int i=0;i<weight;i++){
                serverList.add(server);
            }
        }

        String server=null;

        synchronized(pos){
            if(pos>=serverList.size()){
                pos=0;
            }
            server=serverList.get(pos); 
            pos++;
        }

        return server;
    }

5)加權隨機(Weught Random)法
與加權輪詢法類似,加權隨機法也根據後端服務器不同的配置和負載情況,配置不同的權重

    public static String testWeightRandom(){
        //重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
        Map<String,Integer> serverMap=
            new HashMap<String,Integer>();
        serverMap.putAll(serverWeightMap);
        //取得Ip地址list
        Set<String> keySet=serverMap.keySet();
        Iterator<String> it=keySet.iterator();

        ArrayList<String> serverList=new ArrayList<String>();

        while(it.hasNext()){
            String server=it.next();
            Integer weight=serverMap.get(server);
            for(int i=0;i<weight;i++){
                serverList.add(server);
            }
        }

        String server=null;
        int randomPos = new Random().nextInt(serverList.size());
        server=serverList.get(randomPos);
        return server;
    }

6)最小連接數
根據後端服務器當前的連接情況,動態的選擇其中積壓連接數最少的一臺服務器來處理當前請求。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章