首頁 > 軟體

Java實現5種負載均衡演演算法(小結)

2022-06-01 14:06:11

概念

負載均衡是將使用者端請求存取,通過提前約定好的規則轉發給各個server。其中有好幾個種經典的演演算法,下面我們用Java實現這幾種演演算法。

輪詢演演算法

輪詢演演算法按順序把每個新的連線請求分配給下一個伺服器,最終把所有請求平分給所有的伺服器。

優點:絕對公平

缺點:無法根據伺服器效能去分配,無法合理利用伺服器資源。

package com.monkeyjava.learn.basic.robin;
 
import com.google.common.collect.Lists;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class TestRound {
 
    private Integer  index = 0;
    private List<String> ips = Lists.newArrayList("192.168.1.1", "192.168.1.2", "192.168.1.3");
 
 
    public String roundRobin(){
        String serverIp;
        synchronized(index){
            if (index >= ips.size()){
                index = 0;
            }
            serverIp= ips.get(index);
            //輪詢+1
            index ++;
        }
        return serverIp;
    }
 
    public static void main(String[] args) {
        TestRound testRoundRobin =new TestRound();
        for (int i=0;i< 10 ;i++){
            String serverIp= testRoundRobin.roundRobin();
            System.out.println(serverIp);
        }
    }
}

輸出結果:

192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.1

加權輪詢法

該演演算法中,每個機器接受的連線數量是按權重比例分配的。這是對普通輪詢演演算法的改進,比如你可以設定:第三臺機器的處理能力是第一臺機器的兩倍,那麼負載均衡器會把兩倍的連線數量分配給第3臺機器,輪詢可以將請求順序按照權重分配到後端。

package com.monkeyjava.learn.basic.robin;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class TestWeight {
    private Integer index = 0;
    static Map<String, Integer> ipMap=new HashMap<String, Integer>(16);
    static {
        // 1.map, key-ip,value-權重
        ipMap.put("192.168.1.1", 1);
        ipMap.put("192.168.1.2", 2);
        ipMap.put("192.168.1.3", 4);
 
    }
 
    public List<String> getServerIpByWeight() {
        List<String> ips = new ArrayList<String>(32);
        for (Map.Entry<String, Integer> entry : ipMap.entrySet()) {
            String ip = entry.getKey();
            Integer weight = entry.getValue();
            // 根據權重不同,放入list 中的數量等同於權重,輪詢出的的次數等同於權重
            for (int ipCount =0; ipCount < weight; ipCount++) {
                ips.add(ip);
            }
        }
        return ips;
    }
 
    public String weightRobin(){
        List<String> ips = this.getServerIpByWeight();
        if (index >= ips.size()){
            index = 0;
        }
        String serverIp= ips.get(index);
        index ++;
        return  serverIp;
    }
 
    public static void main(String[] args) {
        TestWeight testWeightRobin=new TestWeight();
        for (int i =0;i< 10 ;i++){
            String server=testWeightRobin.weightRobin();
            System.out.println(server);
        }
    }
}

輸出結果:

192.168.1.1
192.168.1.3
192.168.1.3
192.168.1.3
192.168.1.3
192.168.1.2
192.168.1.2
192.168.1.1
192.168.1.3
192.168.1.3

加權隨機法

獲取帶有權重的亂數字,隨機這種東西,不能看絕對,只能看相對,我們不用index 控制下標進行輪詢,只用random 進行隨機取ip,即實現演演算法。

package com.monkeyjava.learn.basic.robin;
 
import java.util.*;
 
public class TestRandomWeight {
 
    static Map<String, Integer> ipMap=new HashMap<String, Integer>(16);
    static {
        // 1.map, key-ip,value-權重
        ipMap.put("192.168.1.1", 1);
        ipMap.put("192.168.1.2", 2);
        ipMap.put("192.168.1.3", 4);
 
    }
 
    public List<String> getServerIpByWeight() {
        List<String> ips = new ArrayList<String>(32);
        for (Map.Entry<String, Integer> entry : ipMap.entrySet()) {
            String ip = entry.getKey();
            Integer weight = entry.getValue();
            // 根據權重不同,放入list 中的數量等同於權重,輪詢出的的次數等同於權重
            for (int ipCount =0; ipCount < weight; ipCount++) {
                ips.add(ip);
            }
        }
        return ips;
    }
 
    public String randomWeightRobin(){
        List<String> ips = this.getServerIpByWeight();
        //迴圈亂數
        Random random=new Random();
        int index =random.nextInt(ips.size());
        String serverIp = ips.get(index);
        return  serverIp;
    }
 
    public static void main(String[] args) {
        TestRandomWeight testRandomWeightRobin=new TestRandomWeight();
        for (int i =0;i< 10 ;i++){
            String server= testRandomWeightRobin.randomWeightRobin();
            System.out.println(server);
        }
    }
}

輸出結果:

192.168.1.3
192.168.1.3
192.168.1.2
192.168.1.1
192.168.1.2
192.168.1.1
192.168.1.3
192.168.1.2
192.168.1.2
192.168.1.3

隨機法

負載均衡方法隨機的把負載分配到各個可用的伺服器上,通過亂數生成演演算法選取一個伺服器,這種實現演演算法最簡單,隨之呼叫次數增大,這種演演算法可以達到每臺伺服器的請求量接近於平均。

package com.monkeyjava.learn.basic.robin;
 
import com.google.common.collect.Lists;
 
import java.util.List;
import java.util.Random;
 
public class TestRandom {
 
 
    private List<String> ips = Lists.newArrayList("192.168.1.1", "192.168.1.2", "192.168.1.3");
 
 
    public String randomRobin(){
        //亂數
        Random random=new Random();
        int index =random.nextInt(ips.size());
        String serverIp= ips.get(index);
        return  serverIp;
 
    }
 
    public static void main(String[] args) {
        TestRandom testRandomdRobin =new TestRandom();
        for (int i=0;i< 10 ;i++){
            String serverIp= testRandomdRobin.randomRobin();
            System.out.println(serverIp);
        }
    }
}

輸出

192.168.1.3
192.168.1.3
192.168.1.1
192.168.1.2
192.168.1.1
192.168.1.3
192.168.1.2
192.168.1.3
192.168.1.3
192.168.1.2

IP_Hash演演算法

hash(ip)%N演演算法,通過一種雜湊演演算法把使用者端來源IP根據雜湊取模演演算法將請求分配到不同的伺服器上

優點:保證了相同使用者端IP地址將會被雜湊到同一臺後端伺服器,直到後端伺服器列表變更。根據此特性可以在服務消費者與服務提供者之間建立有狀態的session對談

缺點: 如果伺服器進行了下線操作,源IP路由的伺服器IP就會變成另外一臺,如果伺服器沒有做session 共用話,會造成session丟失。

package com.monkeyjava.learn.basic.robin;
 
import com.google.common.collect.Lists;
 
import java.util.List;
 
public class TestIpHash {
 
 
    private List<String> ips = Lists.newArrayList("192.168.1.1", "192.168.1.2", "192.168.1.3");
 
 
    public String ipHashRobin(String clientIp){
        int hashCode=clientIp.hashCode();
        int serverListsize=ips.size();
        int index = hashCode%serverListsize;
        String serverIp= ips.get(index);
        return  serverIp;
 
    }
 
    public static void main(String[] args) {
        TestIpHash testIpHash =new TestIpHash();
        String servername= testIpHash.ipHashRobin("192.168.88.2");
        System.out.println(servername);
    }
}

輸出結果

192.168.1.3

每次執行結果都一樣

到此這篇關於Java實現5種負載均衡演演算法(小結)的文章就介紹到這了,更多相關Java 負載均衡 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com