負載均衡實現之隨機數

負載均衡(LoadBalance),它的職責是將網絡請求,或者其餘形式的負載「均攤」到不一樣的機器上。避免集羣中部分服務器壓力過大,而另外一些服務器比較空閒的狀況。經過負載均衡,可讓每臺服務器獲取到適合本身處理能力的請求。服務器

​ 常見的負載均衡的實現方法有多種,如隨機、輪詢、hash一致性等。本文使用隨機法實現負載均衡。網絡

​ 隨機數法就是幾個數中隨機獲取一個數字,而後獲取這個數據對應的服務器。負載均衡

/**
 * 服務器類
 */
public class Server {
    
    private String serverName;
    
    public Server(String name) {
        this.serverName = name;
    }
    
    public String getServerName() {
        return serverName;
    }
    public void setServerName(String serverName) {
        this.serverName = serverName;
    }

    @Override
    public String toString() {
        return "Server{serverName:"+this.getServerName()+"}";
    }
}
public class LoadBalance_Random {
    //用來存放全部的服務器
    static List<Server> ServerList = new ArrayList<Server>();
    //隨機數生成器
    private static final Random r = new Random();
    
    //初始化   模擬集羣中提供服務的服務器
    static{
        Server server1 = new Server("server1");
        Server server2 = new Server("server2");
        Server server3 = new Server("server3");
        ServerList.add(server1);
        ServerList.add(server2);
        ServerList.add(server3);
    }
    
    public static void main(String[] args) {
        //模擬10個請求來獲取對應的服務器
        for(int i=0;i<10;i++){
            Server server_random = doSelect(ServerList);
            System.out.println(server_random);
        }
    }

    /**
     * 選擇服務器
     * @param serverList
     * @return
     */
    private static Server doSelect(List<Server> serverList) {
        Server server = null;
        //服務器的個數
        int serverNum = serverList.size();
        //隨機獲取一個
        int serverIndex = r.nextInt(serverNum);
        server = serverList.get(serverIndex);
        return server;
    }
}

​ 執行main方法測試,結果以下:dom

​ 在每臺服務器的配置性能等各方面都同樣時,使用這種隨機方法也是可取的,由於每臺服務器獲取的要處理的請求的數據量的機率是同樣的。可是有時候,咱們的服務器不必定都是相同的配置,每一臺服務器的性能都有必定的差別性,致使服務器提供服務的能力的差別,好比上邊咱們有3臺服務器,Server1每秒可處理5個請求,Server2每秒只能處理3個請求,Server3每秒只能處理2個請求,此時若是咱們有10個請求過來了,咱們分別給3個Server3個請求處理,因爲Server3只能處理2個請求,這時就會致使服務3不可用。ide

​ 對這種不一樣服務能力的服務實現負載均衡,咱們可使用加權隨機法。對每一個服務標記權重,提升處理能力強的服務器的權重,下降服務能力若的服務器的權重,即根據能力的大小分配對應比例的請求數。性能

​ 修改上述代碼,給服務加權重測試

/**
 * 服務器類
 */
public class Server {
    
    private String serverName;
    private int weight;//權重
    
    public Server(String name, int weight) {
        this.serverName = name;
        this.weight = weight;
    }
    
    @Override
    public String toString() {
        return "Server{serverName:"+this.getServerName()+",weight:"+this.getWeight()+"}";
    }
    
    // 省略getter 和 setter方法
}

​ 初始化時指定服務器的權重this

//初始化   模擬集羣中提供服務的服務器
    static{
        Server server1 = new Server("server1", 5);
        Server server2 = new Server("server2", 3);
        Server server3 = new Server("server3", 2);
        ServerList.add(server1);
        ServerList.add(server2);
        ServerList.add(server3);
    }

​ 根據權重值獲取服務code

private static Server doSelectWithWeight(List<Server> serverList) {
        Server server = null;
        int totalWeight = 0; //全部服務器的總權重
        boolean isSame = true;//默認全部服務器的權重都相同
        
        for(int i=0; i<serverList.size(); i++){
            //獲取當前服務器得權重
            int serverWeight = serverList.get(i).getWeight();
            //權重累加
            totalWeight = totalWeight + serverWeight;
            //i = 0時默認仍是權重都同樣
            //從第二個開始檢測每一個服務器得權重是否是都同樣,只須要與它得前一個服務得權重相比就能夠了
            if(isSame && i>0){
                int preServerWeight = serverList.get(i-1).getWeight();
                if(serverWeight != preServerWeight){//當前服務器權重和前一個服務器得權重不相同
                    isSame = false;
                }
            }
        }
        
        if(!isSame){//服務器得權重不是都同樣
            //在總權重下獲取一個隨機數 
            int index = r.nextInt(totalWeight);
            //
            for(int i=0;i<serverList.size();i++){
                int serverWeight = serverList.get(i).getWeight();
                //判斷獲取得隨機數落在總權重得哪個區間
                //3臺服務器得得權重分別爲5 3 2  總和爲10  [0到5)這個區間屬於服務器1  [5到8)這個區間屬於服務器2 【8到10)這個區間屬於服務器3
                //如 獲取到得隨機數是6  6-5=1   大於0  說明不在服務器1得區間,遍歷  1-3= -2 小於0  說明它落在了服務器2所在得區間  就能夠得對應服務器
                index = index - serverWeight;
                if(index < 0){
                    return serverList.get(i);
                }
            }
        }else{
            //全部服務器權重都同樣時,按照徹底隨機法隨機獲取一個服務器
            server = doSelect(serverList);
        }
        return server;
    }

​ 使用main方法測試server

public static void main(String[] args) {
        //模擬20個請求獲取對應的服務
        for(int i=0;i<20;i++){
            Server server_random_weight = doSelectWithWeight(ServerList);
            System.out.println(server_random_weight);
        }
    }

測試結果以下

從測試結果圖中能夠看到,權重大的獲取到的請求數多,相反權重小的獲取到的請求數越小。

相關文章
相關標籤/搜索