負(fù)載均衡算法總結(jié)

常見的負(fù)載均衡算法

  • 輪詢法(Round Robin)
  • 加權(quán)輪詢(Weight Round Robin)
  • 隨機算法(Random)
  • 源地址HASH算法(當(dāng)同一IP地址客戶端后端服務(wù)器列表不變時嗜愈,每次都會路由到相同的服務(wù)器hashCode % serverListSize)
  • 加權(quán)隨機法(Weight Random)
  • 最小連接數(shù)法(Least Connections)

隨機(Random)算法

通過系統(tǒng)隨機函數(shù)劝赔,根據(jù)后端服務(wù)器列表的大小值來隨機選取其中一臺進(jìn)行訪問代承。由概率統(tǒng)計理論可以得知焙蹭,隨著調(diào)用量的增大蚌堵,其實際效果越來越接近于平均分配流量到每一臺后端服務(wù)器音比,也就是輪詢的效果

public class RandomTest {
    static List<String> list = Arrays.asList("192.168.0.101","192.168.0.102", "192.168.0.103", "192.168.0.104");
    public static void main(String[] args) throws InterruptedException {
        while (true){
            System.err.println(get());
            TimeUnit.SECONDS.sleep(1);
        }
    }
    private static synchronized String get(){
        // 拷貝服務(wù)列表避免出現(xiàn)由于服務(wù)器上線和下線導(dǎo)致的并發(fā)問題
        List<String> result = new ArrayList<>();
        result.addAll(list);

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

基于概率統(tǒng)計的理論畴蹭,吞吐量越大狼荞,隨機算法的效果越接近于輪詢算法的效果轻腺。因此基本可以替代輪詢算法

加權(quán)隨機(Weight Random)法

與加權(quán)輪詢法類似佑女,加權(quán)隨機法也根據(jù)后端服務(wù)器不同的配置和負(fù)載情況赎婚,配置不同的權(quán)重说庭。不同的是康辑,它是按照權(quán)重來隨機選取服務(wù)器的摄欲,而非順序

/**
     * 實現(xiàn)方法一
     */
    public static String testWeightRandom() {
        // 重新創(chuàng)建一個 map,避免出現(xiàn)由于服務(wù)器上線和下線導(dǎo)致的并發(fā)問題
        Map<String, Integer> serverMap = new HashMap<>();
        serverMap.putAll(serverWeightMap);

        // 取得 IP 地址 list
        Set<String> keySet = serverMap.keySet();
        Iterator<String> it = keySet.iterator();

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

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

        Random random = new Random();
        int randomPos = random.nextInt(serverList.size());
        String server = serverList.get(randomPos);

        return server;
    }

    /**
     * 實現(xiàn)方法二
     */
    public static String testWeightRandom() {
        // 重新創(chuàng)建一個 map疮薇,避免出現(xiàn)由于服務(wù)器上線和下線導(dǎo)致的并發(fā)問題
        Map<String, Integer> serverMap = new HashMap<>();
        serverMap.putAll(serverWeightMap);

        // 計算權(quán)重和
        long weightSum = 0;
        for (String key : serverMap.keySet()) {
            weightSum += serverMap.get(key);
        }

        // 產(chǎn)生隨機數(shù)
        long random = Math.round(Math.random() * weightSum);
        long weight = 0;
        for (String server : serverMap.keySet()) {
            weight += serverMap.get(server);
            if (weight >= random) {
                return server;
            }
        }

        return serverMap.keySet().iterator().next();
    }

輪詢算法(Round-Robin)

輪詢算法是最簡單的一種負(fù)載均衡算法胸墙。它的原理是把來自用戶的請求輪流分配給內(nèi)部的服務(wù)器:從服務(wù)器1開始,直到服務(wù)器N按咒,然后重新開始循環(huán)迟隅。

算法的優(yōu)點是其簡潔性,它無需記錄當(dāng)前所有連接的狀態(tài),所以它是一種無狀態(tài)調(diào)度智袭;

輪詢算法假設(shè)所有服務(wù)器的處理性能都相同奔缠,不關(guān)心每臺服務(wù)器的當(dāng)前連接數(shù)和響應(yīng)速度。當(dāng)請求服務(wù)間隔時間變化比較大時吼野,輪詢算法容易導(dǎo)致服務(wù)器間的負(fù)載不平衡校哎。所以此種均衡算法適合于服務(wù)器組中的所有服務(wù)器都有相同的軟硬件配置并且平均服務(wù)請求相對均衡的情況

偽代碼:

public class LoadBalanceTest {
    static int roundPos = 0;
    static List<String> list = new ArrayList<>();
    public static void main(String[] args) throws InterruptedException {
        while (true){
            System.err.println(loadBalanceOfRound());
            TimeUnit.SECONDS.sleep(1);
        }
    }

    private static synchronized String loadBalanceOfRound(){
        if (roundPos >= list.size() ){
            roundPos = 0;
        }
        return list.get(roundPos++);
    }

    static {
        list.add("192.168.0.101");
        list.add("192.168.0.102");
        list.add("192.168.0.103");
        list.add("192.168.0.104");
    }
}

加權(quán)輪詢算法(WeightedRound-Robin)

輪詢算法并沒有考慮每臺服務(wù)器的處理能力,實際中可能并不是這種情況瞳步。由于每臺服務(wù)器的配置闷哆、安裝的業(yè)務(wù)應(yīng)用等不同,其處理能力會不一樣单起。所以加權(quán)輪詢算法的原理就是:根據(jù)服務(wù)器的不同處理能力抱怔,給每個服務(wù)器分配不同的權(quán)值,使其能夠接受相應(yīng)權(quán)值數(shù)的服務(wù)請求嘀倒;

加權(quán)輪詢算法要生成一個服務(wù)器序列屈留,該序列中包含n個服務(wù)器。n是所有服務(wù)器的權(quán)重之和括儒。在該序列中绕沈,每個服務(wù)器的出現(xiàn)的次數(shù)锐想,等于其權(quán)重值帮寻。并且,生成的序列中赠摇,服務(wù)器的分布應(yīng)該盡可能的均勻固逗。比如序列{a, a, a, a, a, b, c}中,前五個請求都會分配給服務(wù)器a藕帜,這就是一種不均勻的分配方法烫罩,更好的序列應(yīng)該是:{a, a, b, a, c, a, a}。

加權(quán)輪詢算法又可分為:

  • 普通加權(quán)輪詢算法
  • 平滑的加權(quán)輪詢

源地址哈希Hash算法

源地址哈希的思想是獲取客戶端訪問的 IP 地址值洽故,通過哈希函數(shù)計算得到一個數(shù)值贝攒,用該數(shù)值對服務(wù)器列表的大小進(jìn)行取模運算,得到的結(jié)果邊是要訪問的服務(wù)器的序號时甚。采用哈希法進(jìn)行負(fù)載均衡隘弊,同一 IP 地址的客戶端,當(dāng)后端服務(wù)器列表不變時荒适,它每次都會映射到同一臺后端服務(wù)器進(jìn)行訪問

public class RandomTest {
    static List<String> list = Arrays.asList("192.168.0.101", "192.168.0.102", "192.168.0.103", "192.168.0.104");

    public static void main(String[] args) throws InterruptedException {
        while (true) {
            System.err.println(get("10.168.0.101"));
            TimeUnit.SECONDS.sleep(1);
        }
    }

    private static synchronized String get(String ip) {
        // 拷貝服務(wù)列表避免出現(xiàn)由于服務(wù)器上線和下線導(dǎo)致的并發(fā)問題
        List<String> result = new ArrayList<>();
        result.addAll(list);

        int hashCode = System.identityHashCode(ip);
        int size = result.size();
        int index = hashCode % size;

        return result.get(index);
    }
}

通過參數(shù)傳入的客戶端 remoteip 參數(shù)梨熙,取得它的哈希值,對服務(wù)器列表的大小取模刀诬,結(jié)果便是選用的服務(wù)器在服務(wù)器列表中的索引值咽扇。該算法保證了相同的客戶端 IP 地址將會被“哈希”到同一臺后端服務(wù)器,直到后端服務(wù)器列表變更质欲。根據(jù)此特性可以在服務(wù)消費者與服務(wù)提供者之間建立有狀態(tài)的 session 會話

hash算法中,存在以下的幾個問題

1.當(dāng)一臺服務(wù)器宕機了或者新添加一臺機器之后,這個時候hashCode % servers.size()需要重新計算hash值, 如果在緩存的環(huán)境中,所有的請求都會涌向數(shù)據(jù)庫服務(wù)器,給數(shù)據(jù)庫服務(wù)器帶來巨大的壓力,可能導(dǎo)致整個系統(tǒng)不可用,形成雪崩效應(yīng)树埠;

2 .當(dāng)新增了一臺性能強的機器后,利用上述的hash算法無法讓,新增的性能強的服務(wù)器多承擔(dān)壓力;

基于上面的幾個問題,提出了hash算法的改進(jìn):一致性hash算法

最小連接數(shù)(Least Connections)法

最小連接數(shù)算法比較靈活和智能把敞,由于后端服務(wù)器的配置不盡相同弥奸,對于請求的處理有快有慢,它正是根據(jù)后端服務(wù)器當(dāng)前的連接情況奋早,動態(tài)地選取其中當(dāng)前積壓連接數(shù)最小的一臺服務(wù)器來處理當(dāng)前請求盛霎,盡可能地提高后端服務(wù)器的利用效率,將負(fù)載合理地分流到每一臺機器耽装。由于最小連接數(shù)涉及服務(wù)器連接數(shù)的匯總和感知愤炸,設(shè)計與實現(xiàn)比較繁瑣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掉奄,一起剝皮案震驚了整個濱河市规个,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌姓建,老刑警劉巖诞仓,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異速兔,居然都是意外死亡墅拭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門涣狗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谍婉,“玉大人,你說我怎么就攤上這事镀钓∷氚荆” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵丁溅,是天一觀的道長唤蔗。 經(jīng)常有香客問我,道長窟赏,這世上最難降的妖魔是什么妓柜? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮饰序,結(jié)果婚禮上领虹,老公的妹妹穿的比我還像新娘。我一直安慰自己求豫,他們只是感情好塌衰,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布诉稍。 她就那樣靜靜地躺著,像睡著了一般最疆。 火紅的嫁衣襯著肌膚如雪杯巨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天努酸,我揣著相機與錄音服爷,去河邊找鬼。 笑死获诈,一個胖子當(dāng)著我的面吹牛仍源,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舔涎,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼笼踩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了亡嫌?” 一聲冷哼從身側(cè)響起嚎于,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挟冠,沒想到半個月后于购,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡知染,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年肋僧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片持舆。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡色瘩,死狀恐怖伪窖,靈堂內(nèi)的尸體忽然破棺而出逸寓,到底是詐尸還是另有隱情,我是刑警寧澤覆山,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布竹伸,位于F島的核電站,受9級特大地震影響簇宽,放射性物質(zhì)發(fā)生泄漏勋篓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一魏割、第九天 我趴在偏房一處隱蔽的房頂上張望譬嚣。 院中可真熱鬧,春花似錦钞它、人聲如沸拜银。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尼桶。三九已至操灿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泵督,已是汗流浹背趾盐。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留小腊,地道東北人救鲤。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像秩冈,于是被迫代替她去往敵國和親蜒简。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 負(fù)載均衡算法在很多地方都有使用,無論是在服務(wù)治理中或者是在分布式緩存中都大量的使用,本文主要介紹幾種常見的負(fù)載均衡...
    kid_horse閱讀 7,662評論 0 3
  • 【摘要】 面對大量用戶訪問漩仙、高并發(fā)請求搓茬,海量數(shù)據(jù),可以使用高性能的服務(wù)器队他、大型數(shù)據(jù)庫卷仑,存儲設(shè)備,高性能Web服務(wù)器...
    靜修佛緣閱讀 4,559評論 0 24
  • 一麸折、軟件負(fù)載均衡概述 硬件負(fù)載均衡性能優(yōu)越锡凝,功能全面,但是價格昂貴垢啼,一般適合初期或者土豪級公司長期使用窜锯。因此軟件負(fù)...
    程序員技術(shù)圈閱讀 563評論 0 0
  • 前言 前不久公司有個需求是任務(wù)需要按照權(quán)重分配來選擇,當(dāng)時就想到負(fù)載均衡算法里的加權(quán)隨機法芭析,因此對常見的負(fù)載均衡算...
    FlySheep_ly閱讀 1,874評論 2 2
  • 窗前月影動锚扎,疑是故人來; 潮平沙戴露馁启,霜爬兩鬢腮
    菜根譚_閱讀 48評論 0 1