Java實(shí)現(xiàn)5種負(fù)載均衡算法(小結(jié))
概念
負(fù)載均衡是將客戶端請(qǐng)求訪問(wèn),通過(guò)提前約定好的規(guī)則轉(zhuǎn)發(fā)給各個(gè)server。其中有好幾個(gè)種經(jīng)典的算法,下面我們用Java實(shí)現(xiàn)這幾種算法。
輪詢算法
輪詢算法按順序把每個(gè)新的連接請(qǐng)求分配給下一個(gè)服務(wù)器,最終把所有請(qǐng)求平分給所有的服務(wù)器。
優(yōu)點(diǎn):絕對(duì)公平
缺點(diǎn):無(wú)法根據(jù)服務(wù)器性能去分配,無(wú)法合理利用服務(wù)器資源。
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); } } }
輸出結(jié)果:
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
加權(quán)輪詢法
該算法中,每個(gè)機(jī)器接受的連接數(shù)量是按權(quán)重比例分配的。這是對(duì)普通輪詢算法的改進(jìn),比如你可以設(shè)定:第三臺(tái)機(jī)器的處理能力是第一臺(tái)機(jī)器的兩倍,那么負(fù)載均衡器會(huì)把兩倍的連接數(shù)量分配給第3臺(tái)機(jī)器,輪詢可以將請(qǐng)求順序按照權(quán)重分配到后端。
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-權(quán)重 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(); // 根據(jù)權(quán)重不同,放入list 中的數(shù)量等同于權(quán)重,輪詢出的的次數(shù)等同于權(quán)重 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); } } }
輸出結(jié)果:
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
加權(quán)隨機(jī)法
獲取帶有權(quán)重的隨機(jī)數(shù)字,隨機(jī)這種東西,不能看絕對(duì),只能看相對(duì),我們不用index 控制下標(biāo)進(jìn)行輪詢,只用random 進(jìn)行隨機(jī)取ip,即實(shí)現(xiàn)算法。
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-權(quán)重 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(); // 根據(jù)權(quán)重不同,放入list 中的數(shù)量等同于權(quán)重,輪詢出的的次數(shù)等同于權(quán)重 for (int ipCount =0; ipCount < weight; ipCount++) { ips.add(ip); } } return ips; } public String randomWeightRobin(){ List<String> ips = this.getServerIpByWeight(); //循環(huán)隨機(jī)數(shù) 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); } } }
輸出結(jié)果:
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
隨機(jī)法
負(fù)載均衡方法隨機(jī)的把負(fù)載分配到各個(gè)可用的服務(wù)器上,通過(guò)隨機(jī)數(shù)生成算法選取一個(gè)服務(wù)器,這種實(shí)現(xiàn)算法最簡(jiǎn)單,隨之調(diào)用次數(shù)增大,這種算法可以達(dá)到每臺(tái)服務(wù)器的請(qǐng)求量接近于平均。
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(){ //隨機(jī)數(shù) 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算法,通過(guò)一種散列算法把客戶端來(lái)源IP根據(jù)散列取模算法將請(qǐng)求分配到不同的服務(wù)器上
優(yōu)點(diǎn):保證了相同客戶端IP地址將會(huì)被哈希到同一臺(tái)后端服務(wù)器,直到后端服務(wù)器列表變更。根據(jù)此特性可以在服務(wù)消費(fèi)者與服務(wù)提供者之間建立有狀態(tài)的session會(huì)話
缺點(diǎn): 如果服務(wù)器進(jìn)行了下線操作,源IP路由的服務(wù)器IP就會(huì)變成另外一臺(tái),如果服務(wù)器沒(méi)有做session 共享話,會(huì)造成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); } }
輸出結(jié)果
192.168.1.3
每次運(yùn)行結(jié)果都一樣
到此這篇關(guān)于Java實(shí)現(xiàn)5種負(fù)載均衡算法(小結(jié))的文章就介紹到這了,更多相關(guān)Java 負(fù)載均衡 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 使用Java實(shí)現(xiàn)6種常見(jiàn)負(fù)載均衡算法
- Java負(fù)載均衡算法實(shí)現(xiàn)之輪詢和加權(quán)輪詢
- java開(kāi)發(fā)Dubbo負(fù)載均衡與集群容錯(cuò)示例詳解
- 使用Java實(shí)現(xiàn)5種負(fù)載均衡算法實(shí)例
- Java Grpc實(shí)例創(chuàng)建負(fù)載均衡詳解
- 詳解Java實(shí)現(xiàn)負(fù)載均衡的幾種算法代碼
- Java?Ribbon與openfeign區(qū)別和用法講解
- Java中的服務(wù)發(fā)現(xiàn)與負(fù)載均衡及Eureka與Ribbon的應(yīng)用小結(jié)
相關(guān)文章
Java fastdfs客戶端實(shí)現(xiàn)上傳下載文件
這篇文章主要介紹了Java fastdfs客戶端實(shí)現(xiàn)上傳下載文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10MyBatisPlus3.4.3版自動(dòng)生成代碼的使用過(guò)程
這篇文章主要介紹了MyBatisPlus3.4.3版自動(dòng)生成代碼的使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04Java優(yōu)先隊(duì)列(PriorityQueue)重寫(xiě)compare操作
這篇文章主要介紹了Java優(yōu)先隊(duì)列(PriorityQueue)重寫(xiě)compare操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10Java中的遞增i++與++i的實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Java中的i++與++i的實(shí)現(xiàn)原理詳解,在Java中,i++是一種常見(jiàn)的遞增操作符,用于將變量i的值增加1,它是一種簡(jiǎn)潔且方便的方式來(lái)實(shí)現(xiàn)循環(huán)和計(jì)數(shù)功能,i++可以用于各種情況,本文來(lái)看一下其實(shí)現(xiàn)原理,需要的朋友可以參考下2023-10-10JAVA中出現(xiàn)異常、拋出異常后續(xù)代碼是否執(zhí)行情況詳析
當(dāng)產(chǎn)生異常后,并在異常處理器中進(jìn)行執(zhí)行之后,程序會(huì)是如何的一種狀態(tài),是終止還是繼續(xù)執(zhí)行處理之后的代碼呢,下面這篇文章主要給大家介紹了關(guān)于JAVA中出現(xiàn)異常、拋出異常后續(xù)代碼是否執(zhí)行情況的相關(guān)資料,需要的朋友可以參考下2024-05-05