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 发布!