Ribbon客戶端組件提供一系列完善的配置選項,好比鏈接超時、重試、重試算法等,內置可插拔、可定製的負載均衡組件。下面是用到的一些負載均衡策略:java
先寫一個類模擬一個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,也就是更傾向於選擇發出調用的服務所在的託管區域內,這樣可用下降延遲,節省成本)選擇目標服務實例。它監控每一個區域中運行的實例的運維行爲,並且可以實時快速丟棄一整個區域。在面對整個區域的故障時,這幫咱們提高了彈性。
一、負載均衡器會檢查、計算全部可用區域的狀態。若是某個區域中平均每一個服務器的活躍請求已經達到配置的閾值,該區域將從活躍服務器列表中排除。若是多於一個區域已經到達閾值,平均每服務器擁有最多活躍請求的區域將被排除。服務器
二、最差的區域被排除後,從剩下的區域中,將按照服務器實例數的機率抽樣法選擇一個區域。 三、從選定區域中,將會根據給定負載均衡策略規則返回一個服務器。
將請求按順序輪流地分配到後端服務器上,它均衡地對待後端的每一臺服務器,而不關心服務器實際的鏈接數和當前的系統負載。代碼實現大體以下:架構
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; } }
不一樣的後端服務器可能機器的配置和當前系統的負載並不相同,所以它們的抗壓能力也不相同。給配置高、負載低的機器配置更高的權重,讓其處理更多的請;而配置低、負載高的機器,給其分配較低的權重,下降其系統負載,加權輪詢能很好地處理這一問題,並將請求順序且按照權重分配到後端。代碼大體以下:併發
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); } }
更多資料: 2020 年 精選阿里 Java、架構、微服務精選等,加 v ❤ :gongchengshi6678運維
本文由博客一文多發平臺 OpenWrite 發佈!