本文参考自 负载均衡算法及手段
负载均衡算法
private Map<String, Integer> serverMap = new HashMap<>(){ {
put("192.168.1.100", 1);
put("192.168.1.101", 1);
put("192.168.1.102", 4);
put("192.168.1.103", 1);
put("192.168.1.104", 1);
put("192.168.1.105", 3);
put("192.168.1.106", 1);
put("192.168.1.107", 2);
put("192.168.1.108", 1);
put("192.168.1.109", 1);
put("192.168.1.110", 1);
} };
1、随机算法
- Random:随机,按权重设置随机概率。在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
public void random(){ List<String> keyList = new ArrayList<String>(serverMap.keySet()); Random random = new Random(); int idx = random.nextInt(keyList.size()); String server = keyList.get(idx); System.out.println(server); }
- WeightedRandom
public void weightRandom(){ Set<String> keySet = serverMap.keySet(); List<String> servers = new ArrayList<String>(); for(Iterator<String> it = keySet.iterator();it.hasNext();){ String server = it.next(); int weithgt = serverMap.get(server); for(int i=0;i<weithgt;i++) servers.add(server); } String server = null; Random random = new Random(); int idx = random.nextInt(servers.size()); server = servers.get(idx); System.out.println(server); }
2、轮询及加权轮询
- 轮询 (Round Robbin):当服务器群中各服务器的处理能力相同时,且每笔业务处理量差异不大时,最适合使用这种算法。 轮循,按公约后的权重设置轮循比率。存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
private Integer pos = 0; public void roundRobin(){ List<String> keyList = new ArrayList<>(serverMap.keySet()); String server = null; synchronized (pos){ if(pos > keyList.size()) pos = 0; server = keyList.get(pos); pos++; } System.out.println(server); }
- 加权轮询 (Weighted Round Robbin):为轮询中的每台服务器附加一定权重的算法。比如服务器1权重1,服务器2权重2,服务器3权重3,则顺序为1-2-2-3-3-3-1-2-2-3-3-3- ……
public void weightRoundRobin(){ Set<String> keySet = serverMap.keySet(); List<String> servers = new ArrayList<>(); for(Iterator<String> it = keySet.iterator();it.hasNext();){ String server = it.next(); int weithgt = serverMap.get(server); for(int i=0;i<weithgt;i++) servers.add(server); } String server = null; synchronized (pos){ if(pos > keySet.size()) pos = 0; server = servers.get(pos); pos++; } System.out.println(server); }
3、最小连接及加权最小连接
-
最少连接 (Least Connections):在多个服务器中,与处理连接数(会话数)最少的服务器进行通信的算法。即使在每台服务器处理能力各不相同,每笔业务处理量也不相同的情况下,也能够在一定程度上降低服务器的负载。
-
加权最少连接 (Weighted Least Connection):为最少连接算法中的每台服务器附加权重的算法,该算法事先为每台服务器分配处理连接的数量,并将客户端请求转至连接数最少的服务器上。
4、哈希算法
- 普通哈希
public void hash(){ List<String> keyList = new ArrayList<String>(serverMap.keySet()); String remoteIp = "192.168.2.215"; int hashCode = remoteIp.hashCode(); int idx = hashCode % keyList.size(); String server = keyList.get(Math.abs(idx)); System.out.println(server); }
- 一致性哈希:相同参数的请求总是发到同一提供者。当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
5、IP 地址散列
通过管理发送方 IP 和目的地 IP 地址的散列,将来自同一发送方的分组(或发送至同一目的地的分组)统一转发到相同服务器的算法。当客户端有一系列业务需要处理而必须和一个服务器反复通信时,该算法能够以流(会话)为单位,保证来自相同客户端的通信能够一直在同一服务器中进行处理。
6、URL 散列
通过管理客户端请求 URL 信息的散列,将发送至相同URL的请求转发至同一服务器的算法。