1)輪訓(Round Robin)法
此算法將請求按順序輪流的分配到後端服務器,他均衡的對待後臺每一臺服務器,而不關心服務器實際的連接數和當前的系統負載
public class RoundRobin {
private static Map<String,Integer> serverWeightMap=new HashMap<String,Integer>();
private static volatile Integer pos=new Integer(0);
static{
serverWeightMap.put("192.168.1.100",1);
serverWeightMap.put("192.168.1.101",1);
serverWeightMap.put("192.168.1.102",4);
serverWeightMap.put("192.168.1.103",1);
serverWeightMap.put("192.168.1.104",1);
serverWeightMap.put("192.168.1.105",3);
serverWeightMap.put("192.168.1.106",1);
serverWeightMap.put("192.168.1.107",2);
serverWeightMap.put("192.168.1.108",1);
serverWeightMap.put("192.168.1.109",1);
serverWeightMap.put("192.168.1.110",1);
}
public static void main(String[] args) {
for(int i=0;i<100;i++){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(testRoundRobin());
}
}).start();
}
}
public static String testRoundRobin(){
//重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
Map<String,Integer> serverMap=
new HashMap<String,Integer>();
serverMap.putAll(serverWeightMap);
//取得Ip地址list
Set<String> keySet=serverMap.keySet();
ArrayList<String> keyList=new ArrayList<String>();
keyList.addAll(keySet);
String server=null;
synchronized(pos){
if(pos>=keySet.size()){
pos=0;
}
server=keyList.get(pos);
pos++;
}
return server;
}
}
2)隨機(Random)法
通過系統隨機函數,根據後端服務器列表的大小值來隨機選取其中一臺進行訪問。由概率統計論得知,隨着調用量的增大,其實際效果越來越接近平均分配流浪到每一臺後端服務器。
public static String testRandom(){
//重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
Map<String,Integer> serverMap=
new HashMap<String,Integer>();
serverMap.putAll(serverWeightMap);
//取得Ip地址list
Set<String> keySet=serverMap.keySet();
ArrayList<String> keyList=new ArrayList<String>();
keyList.addAll(keySet);
int randomPos = new Random().nextInt(keyList.size());
return keyList.get(randomPos);
}
3)源地址哈希(Hash)法
源地址哈希法的思想是獲取客戶端訪問的IP地址,通過哈希函數計算得到一個數值,用該數值對服務器列表的大小進行取模運算,得到的結果便是要訪問的服務器的序號。採用哈希法進行負載均衡,當後端服務器列表不變時,同一IP地址的客戶端,每次都會被影射到同一臺後端服務器。
public static String testConsumerHash(String remoteip){
//重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
Map<String,Integer> serverMap=
new HashMap<String,Integer>();
serverMap.putAll(serverWeightMap);
//取得Ip地址list
Set<String> keySet=serverMap.keySet();
ArrayList<String> keyList=new ArrayList<String>();
keyList.addAll(keySet);
int hashCode=remoteip.hashCode();
int size=keyList.size();
int serverPos=hashCode%size;
//此處服務器key是其Ip哈希值(hashCode%size)
return keyList.get(serverPos);
}
4)加權輪詢法
不同的後端服務器可能機器的配置和當前系統的負載並不相同,因此它們的抗壓能力也不盡相同。給配置高的、負載低的機器更高的權重,讓其處理更多請求,而低配置、負載高的機器,則給其分配較低的權重,降低其系統負載。
public static String testWeightRoundRobin(){
//重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
Map<String,Integer> serverMap=
new HashMap<String,Integer>();
serverMap.putAll(serverWeightMap);
//取得Ip地址list
Set<String> keySet=serverMap.keySet();
Iterator<String> it=keySet.iterator();
ArrayList<String> serverList=new ArrayList<String>();
while(it.hasNext()){
String server=it.next();
Integer weight=serverMap.get(server);
for(int i=0;i<weight;i++){
serverList.add(server);
}
}
String server=null;
synchronized(pos){
if(pos>=serverList.size()){
pos=0;
}
server=serverList.get(pos);
pos++;
}
return server;
}
5)加權隨機(Weught Random)法
與加權輪詢法類似,加權隨機法也根據後端服務器不同的配置和負載情況,配置不同的權重
public static String testWeightRandom(){
//重新創建一個map,避免出現由於服務器上線和下線導致的併發問題
Map<String,Integer> serverMap=
new HashMap<String,Integer>();
serverMap.putAll(serverWeightMap);
//取得Ip地址list
Set<String> keySet=serverMap.keySet();
Iterator<String> it=keySet.iterator();
ArrayList<String> serverList=new ArrayList<String>();
while(it.hasNext()){
String server=it.next();
Integer weight=serverMap.get(server);
for(int i=0;i<weight;i++){
serverList.add(server);
}
}
String server=null;
int randomPos = new Random().nextInt(serverList.size());
server=serverList.get(randomPos);
return server;
}
6)最小連接數
根據後端服務器當前的連接情況,動態的選擇其中積壓連接數最少的一臺服務器來處理當前請求。