Java程式碼實現負載均衡五種演算法
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u012904383/article/details/78358354
前言:
負載均衡是為了解決併發情況下,多個請求訪問,把請求通過提前約定好的規則轉發給各個server。其中有好幾個種經典的演算法。在用java程式碼編寫這幾種演算法之前,先來了解一下負載均衡這個概念。
1.概念
負載,從字面意思可以分析,是指後端server可以承受的壓力。這個一方面是伺服器的效能,另一方面就是程式碼的質量了。
均衡,就是說把服務部署在多型server,如何排程這些資源。根據伺服器效能不同,進行一個權衡。
當web訪問量增加,伺服器效能不同,更好的去利用伺服器,我們需要負載均衡演算法。
2.幾種負載均衡演算法簡介
主要的負載均衡演算法是圖中這些,在程式碼實現之前,我們先簡單回顧一下他們的概念。
輪詢法:
輪詢演算法按順序把每個新的連線請求分配給下一個伺服器,最終把所有請求平分給所有的伺服器。
優點:絕對公平
缺點:無法根據伺服器效能去分配,無法合理利用伺服器資源。
加權輪詢法:
該演算法中,每個機器接受的連線數量是按權重比例分配的。這是對普通輪詢演算法的改進,比如你可以設定:第三臺機器的處理能力是第一臺機器的兩倍,那麼負載均衡器會把兩倍的連線數量分配給第3臺機器。加權輪詢分為:簡單的輪詢、平滑的輪詢。
什麼是平滑的輪詢,就是把每個不同的服務,平均分佈。在Nginx原始碼中,實現了一種叫做平滑的加權輪詢(smooth weighted round-robin balancing)的演算法,它生成的序列更加均勻。5個請求現在分散開來,不再是連續的。
隨機法:
負載均衡方法隨機的把負載分配到各個可用的伺服器上,通過隨機數生成演算法選取一個伺服器。畢竟隨機,,有效性受到了質疑。
加權隨機法:
獲取帶有權重的隨機數字,隨機這種東西,不能看絕對,只能看相對。
IP_Hash演算法:
hash(object)%N演算法,通過一種雜湊演算法把請求分配到不同的伺服器上。
3.Java程式碼實現負載均衡五種演算法
1.輪詢法:
/**
* Title:輪詢
* Description:
*
* @author Created by Julie
* @version 1.0
* @date on 15:49 2017/10/26
*/
package com.test.loadbalance;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class TestRoundRobin {
// 1.定義map, key-ip,value-weight
static Map<String,Integer> ipMap=new HashMap<>();
static {
ipMap.put("192.168.13.1",1);
ipMap.put("192.168.13.2",1);
ipMap.put("192.168.13.3",1);
}
// Integer sum=0;
Integer pos = 0;
public String RoundRobin(){
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);
// 2.取出來key,放到set中
Set<String> ipset=ipServerMap.keySet();
// 3.set放到list,要迴圈list取出
ArrayList<String> iplist=new ArrayList<String>();
iplist.addAll(ipset);
String serverName=null;
// 4.定義一個迴圈的值,如果大於set就從0開始
synchronized(pos){
if (pos>=ipset.size()){
pos=0;
}
serverName=iplist.get(pos);
//輪詢+1
pos ++;
}
return serverName;
}
public static void main(String[] args) {
TestRoundRobin testRoundRobin=new TestRoundRobin();
for (int i=0;i<10;i++){
String serverIp=testRoundRobin.RoundRobin();
System.out.println(serverIp);
}
}
}
2.加權輪詢法
package com.test.loadbalance;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Title:
* Description:加權輪詢
*
* @author Created by Julie
* @version 1.0
* @date on 18:05 2017/10/26
*/
public class TestWeightRobin {
// 1.map, key-ip,value-weight
static Map<String,Integer> ipMap=new HashMap<>();
static {
ipMap.put("192.168.13.1",1);
ipMap.put("192.168.13.2",2);
ipMap.put("192.168.13.3",4);
}
Integer pos=0;
public String WeightRobin(){
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);
Set<String> ipSet=ipServerMap.keySet();
Iterator<String> ipIterator=ipSet.iterator();
//定義一個list放所有server
ArrayList<String> ipArrayList=new ArrayList<String>();
//迴圈set,根據set中的可以去得知map中的value,給list中新增對應數字的server數量
while (ipIterator.hasNext()){
String serverName=ipIterator.next();
Integer weight=ipServerMap.get(serverName);
for (int i = 0;i < weight ;i++){
ipArrayList.add(serverName);
}
}
String serverName=null;
if (pos>=ipArrayList.size()){
pos=0;
}
serverName=ipArrayList.get(pos);
//輪詢+1
pos ++;
return serverName;
}
public static void main(String[] args) {
TestWeightRobin testWeightRobin=new TestWeightRobin();
for (int i =0;i<10;i++){
String server=testWeightRobin.WeightRobin();
System.out.println(server);
}
}
}
3.隨機法:
package com.test.loadbalance;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Title:
* Description:隨機
*
* @author Created by Julie
* @version 1.0
* @date on 18:25 2017/10/26
*/
public class TestRandom {
// 1.定義map, key-ip,value-weight
static Map<String,Integer> ipMap=new HashMap<>();
static {
ipMap.put("192.168.13.1",1);
ipMap.put("192.168.13.2",2);
ipMap.put("192.168.13.3",4);
}
public String Random() {
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);
Set<String> ipSet=ipServerMap.keySet();
//定義一個list放所有server
ArrayList<String> ipArrayList=new ArrayList<String>();
ipArrayList.addAll(ipSet);
//迴圈隨機數
Random random=new Random();
//隨機數在list數量中取(1-list.size)
int pos=random.nextInt(ipArrayList.size());
String serverNameReturn= ipArrayList.get(pos);
return serverNameReturn;
}
public static void main(String[] args) {
TestRandom testRandom=new TestRandom();
for (int i =0;i<10;i++){
String server=testRandom.Random();
System.out.println(server);
}
}
}
4.加權隨機:
package com.test.loadbalance;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Title:
* Description:加權隨機
*
* @author Created by Julie
* @version 1.0
* @date on 18:42 2017/10/26
*/
public class TestRobinRandom {
// 1.定義map, key-ip,value-weight
static Map<String,Integer> ipMap=new HashMap<>();
static {
ipMap.put("192.168.13.1",1);
ipMap.put("192.168.13.2",2);
ipMap.put("192.168.13.3",4);
}
public String RobinRandom(){
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);
Set<String> ipSet=ipServerMap.keySet();
Iterator<String> ipIterator=ipSet.iterator();
//定義一個list放所有server
ArrayList<String> ipArrayList=new ArrayList<String>();
//迴圈set,根據set中的可以去得知map中的value,給list中新增對應數字的server數量
while (ipIterator.hasNext()){
String serverName=ipIterator.next();
Integer weight=ipServerMap.get(serverName);
for (int i=0;i<weight;i++){
ipArrayList.add(serverName);
}
}
//迴圈隨機數
Random random=new Random();
//隨機數在list數量中取(1-list.size)
int pos=random.nextInt(ipArrayList.size());
String serverNameReturn= ipArrayList.get(pos);
return serverNameReturn;
}
public static void main(String[] args) {
TestRobinRandom testRobinRandom=new TestRobinRandom();
for (int i =0;i<10;i++){
String server=testRobinRandom.RobinRandom();
System.out.println(server);
}
}
}
5.IP_Hash演算法:
package com.test.loadbalance;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Title:
* Description:
*
* @author Created by Julie
* @version 1.0
* @date on 18:35 2017/10/26
*/
public class ipHash {
// 1.定義map, key-ip,value-weight
static Map<String,Integer> ipMap=new HashMap<>();
static {
ipMap.put("192.168.13.1",1);
ipMap.put("192.168.13.2",2);
ipMap.put("192.168.13.3",4);
}
public String ipHash(String clientIP){
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);
// 2.取出來key,放到set中
Set<String> ipset=ipServerMap.keySet();
// 3.set放到list,要迴圈list取出
ArrayList<String> iplist=new ArrayList<String>();
iplist.addAll(ipset);
//對ip的hashcode值取餘數,每次都一樣的
int hashCode=clientIP.hashCode();
int serverListsize=iplist.size();
int pos=hashCode%serverListsize;
return iplist.get(pos);
}
public static void main(String[] args) {
ipHash iphash=new ipHash();
String servername= iphash.ipHash("192.168.21.2");
System.out.println(servername);
}
}
---------------------
作者:我是周洲
來源:CSDN
原文:https://blog.csdn.net/zhou2s_101216/article/details/78358354
版權宣告:本文為博主原創文章,轉載請附上博文連結!