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);
}
}
文末福利
Java 資料大全 連結:https://pan.baidu.com/s/1pUCCPstPnlGDCljtBVUsXQ 密碼:b2xc
更多資料: 2020 年 精選阿里 Java、架構、微服務精選資料等,加 v ❤ :qwerdd111
轉載,請保留原文地址,謝謝 ~