Spring Cloud Ribbon 用戶端負載均衡
Ribbon用戶端元件提供一系列完善的配置選項,比如連接配接逾時、重試、重試算法等,内置可插拔、可定制的負載均衡元件。下面是用到的一些負載均衡政策:
簡單輪詢負載均衡
權重輪詢負載均衡
區域感覺輪詢負載均衡
随機負載均衡
先寫一個類模拟一個IP清單:
public class IpMap
{
// 待路由的Ip清單,Key代表Ip,Value代表該Ip的權重
public static HashMap<String, Integer> serverWeightMap =
new HashMap<String, Integer>();
static
{
serverWeightMap.put("192.168.1.100", 1);
serverWeightMap.put("192.168.1.101", 1);
// 權重為4
serverWeightMap.put("192.168.1.102", 4);
serverWeightMap.put("192.168.1.103", 1);
serverWeightMap.put("192.168.1.104", 1);
// 權重為3
serverWeightMap.put("192.168.1.105", 3);
serverWeightMap.put("192.168.1.106", 1);
// 權重為2
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);
}
}
區域感覺負載均衡
在選擇伺服器時,該負載均衡器會采取如下步驟:
區域感覺負載均衡器内置電路跳閘邏輯,可被配置基于區域同源關系(Zone Affinity,也就是更傾向于選擇發出調用的服務所在的托管區域内,這樣可用降低延遲,節省成本)選擇目标服務執行個體。它監控每個區域中運作的執行個體的運維行為,而且能夠實時快速丢棄一整個區域。在面對整個區域的故障時,這幫我們提升了彈性。
1、負載均衡器會檢查、計算所有可用區域的狀态。如果某個區域中平均每個伺服器的活躍請求已經達到配置的門檻值,該區域将從活躍伺服器清單中排除。如果多于一個區域已經到達門檻值,平均每伺服器擁有最多活躍請求的區域将被排除。
2、最差的區域被排除後,從剩下的區域中,将按照伺服器執行個體數的機率抽樣法選擇一個區域。
3、從標明區域中,将會根據給定負載均衡政策規則傳回一個伺服器。
簡單輪詢算法
将請求按順序輪流地配置設定到後端伺服器上,它均衡地對待後端的每一台伺服器,而不關心伺服器實際的連接配接數和目前的系統負載。代碼實作大緻如下:
public class RoundRobin
private static Integer pos = 0;
public static String getServer()
{
// 重建一個Map,避免伺服器的上下線導緻的并發問題
Map<String, Integer> serverMap =
new HashMap<String, Integer>();
serverMap.putAll(IpMap.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;
}
優點:試圖做到請求轉移的絕對均衡。
缺點:為了做到請求轉移的絕對均衡,必須付出相當大的代價,因為為了保證pos變量修改的互斥性,需要引入重量級的悲觀鎖synchronized,這将會導緻該段輪詢代碼的并發吞吐量發生明顯的下降。
權重輪詢算法
不同的後端伺服器可能機器的配置和目前系統的負載并不相同,是以它們的抗壓能力也不相同。給配置高、負載低的機器配置更高的權重,讓其處理更多的請;而配置低、負載高的機器,給其配置設定較低的權重,降低其系統負載,權重輪詢能很好地處理這一問題,并将請求順序且按照權重配置設定到後端。代碼大緻如下:
public class WeightRoundRobin
private static Integer pos;
public static String getServer()
{
// 重建一個Map,避免伺服器的上下線導緻的并發問題
Map<String, Integer> serverMap =
new HashMap<String, Integer>();
serverMap.putAll(IpMap.serverWeightMap);
// 取得Ip位址List
Set<String> keySet = serverMap.keySet();
Iterator<String> iterator = keySet.iterator();
List<String> serverList = new ArrayList<String>();
while (iterator.hasNext())
{
String server = iterator.next();
int weight = serverMap.get(server);
for (int i = 0; i < weight; i++)
serverList.add(server);
}
String server = null;
synchronized (pos)
{
if (pos > keySet.size())
pos = 0;
server = serverList.get(pos);
pos ++;
}
return server;
}
通過系統的随機算法,根據後端伺服器的清單大小值來随機選取其中的一台伺服器進行通路。由機率統計理論可以得知,随着用戶端調用服務端的次數增多,其實際效果越來越接近于平均配置設定調用量到後端的每一台伺服器,也就是輪詢的結果。大緻代碼如下:
public class Random
public static String getServer()
{
// 重建一個Map,避免伺服器的上下線導緻的并發問題
Map<String, Integer> serverMap =
new HashMap<String, Integer>();
serverMap.putAll(IpMap.serverWeightMap);
// 取得Ip位址List
Set<String> keySet = serverMap.keySet();
ArrayList<String> keyList = new ArrayList<String>();
keyList.addAll(keySet);
java.util.Random random = new java.util.Random();
int randomPos = random.nextInt(keyList.size());
return keyList.get(randomPos);
}
原文位址
https://www.cnblogs.com/Alandre/p/13041113.html