转自;https://www.xttblog.com/?p=4012
1.常见的负载均衡算法有7种:
1.完全随机算法
2.加权随机算法
3.完全轮询(Round Robin)算法
4.加权轮询算法
5.平滑加权轮询算法
6.哈希算法
7.最小压力算法
完全随机算法:
实现原理:随机从负载中获取一台机器。
// 完全随机算法 public String absoluteRandom() { // 服务器列表 List<String> serverList = new ArrayList<>(); serverList.add("server1"); serverList.add("server2"); serverList.add("server3"); Random random = new Random(); int randomNum = random.nextInt(serverList.size()); String selectServer = serverList.get(randomNum); return selectServer; }
加权随机算法:
实现原理:根据配置的权重大小,往服务器列表中存入的当前服务器的数量等于权重多少,再根据列表总数生成随机数取执行的服务器。
// 加权随机算法 public String weightRandom() { Map<String, Integer> serverMap = new HashMap<>(4); serverMap.put("sever1", 3); serverMap.put("server2", 5); serverMap.put("server3", 2); Set<Map.Entry<String, Integer>> me = serverMap.entrySet(); List<String> serverList = new ArrayList<>(); for (Map.Entry<String, Integer> entry : me) { // 遍历权重大小往服务器列表中塞值 for (int i = 0; i < entry.getValue(); i++) { serverList.add(entry.getKey()); } } Random random = new Random(); int randomNum = random.nextInt(serverList.size()); return serverList.get(randomNum); }
完全轮询算法:
实现原理:按顺序依次接收请求
// 完全轮询算法 int index = 0; public String absolutePoll() { // 服务器列表 List<String> serverList = new ArrayList<>(); serverList.add("server1"); serverList.add("server2"); serverList.add("server3"); if (index == serverList.size()) { index = 0; } return serverList.get(index++); }
加权轮询算法:
// 加权轮询算法 int index = 0; public String weightPoll() { Map<String, Integer> serverMap = new HashMap<>(4); serverMap.put("sever1", 3); serverMap.put("server2", 5); serverMap.put("server3", 2); Set<Map.Entry<String, Integer>> me = serverMap.entrySet(); List<String> serverList = new ArrayList<>(); for (Map.Entry<String, Integer> entry : me) { // 遍历权重大小往服务器列表中塞值 for (int i = 0; i < entry.getValue(); i++) { serverList.add(entry.getKey()); } } if (index == serverList.size()) { index = 0; } return serverList.get(index++); }
平滑加权轮询算法:
加权轮询可能在实际中会出现某个服务器权重大,导致长时间执行,一旦遇到耗时大的请求,压力非常的大,存在着不合理性,因此又有了平滑加权轮询算法。
平滑加权算法不仅使权重配置高的服务器轮询的次数多,而且不会使多个请求一直轮询到同一个此服务器上。
假设有n太服务器,S={S1,S2,...,Sn},配置权重W={W1,W2,...,Wn},有效权重CW={CW1,CW2,...,CWn}。每个服务器除了存在一个配置权重外还有一个当前的有效权重CWi,且CWi的初始值等于Wi;
currentServer表示当前选中的服务器,初始值为-1,所有服务器的配置权重和为allWeightSum。
步骤:
1、初始每个服务器i的当前有效权重CWi为配置权重Wi,并求得配置权重和allWeightSum;
2、选出当前有效权重最大的服务器,那么currentServer的值指向它,将当前有效权重CWi减去所有服务器的配置权重和allWeightSum
3、将每台服务器i的当前有效权重CWi都加上配置权重Wi
4、取到变量currentServer指向的服务器
5、每次轮询循环2,3,4步骤
private static Map<String, SmoothWeightServer> serverMap = new HashMap<>(); /** * 所有服务器的配置权重和 */ static int allWeightSum; static { serverMap.put("server1", new SmoothWeightServer(5, 5, "server1")); serverMap.put("server2", new SmoothWeightServer(1, 1, "server2")); serverMap.put("server3", new SmoothWeightServer(2, 2, "server3")); // for (Map.Entry<String, SmoothWeightServer> entry : serverMap.entrySet()) { // SmoothWeightServer currentServer = entry.getValue(); // // 配置权重值之和 // allWeightSum += currentServer.getWeight(); // } allWeightSum = 8; } /** * 平滑加权轮询 * * @return */ public static String smoothPoll() { SmoothWeightServer maxWeightServer = null; for (Map.Entry<String, SmoothWeightServer> entry : serverMap.entrySet()) { SmoothWeightServer currentServer = entry.getValue(); // 配置权重值只获取一次即可 if (maxWeightServer == null || currentServer.getCurrentWeight() > maxWeightServer.getCurrentWeight()) { maxWeightServer = currentServer; } } // 将当前选中的服务器的当前有效权重值减去总配置权重值,将每台服务器加上当前服务器的配置权重 maxWeightServer.setCurrentWeight(maxWeightServer.getCurrentWeight() - allWeightSum); for (Map.Entry<String, SmoothWeightServer> entry : serverMap.entrySet()) { SmoothWeightServer currentServer = entry.getValue(); currentServer.setCurrentWeight(currentServer.getCurrentWeight() + currentServer.getWeight()); } return maxWeightServer.getIp(); } public static void main(String[] args) { for (int i = 0; i < 100; i++) { System.out.println(smoothPoll()); } }
哈希负载均衡算法
实现原理:在集群环境下,让同一个用户的访问,分流到同一台服务器上。根据客户端的ip地址通过哈希运算得到一个哈希值,将此哈希值和服务器的总数取模,得到的值就是选择的服务器的下标
public String hashPoll(String clientIp) { // 服务器列表 List<String> serverList = new ArrayList<>(); serverList.add("server1"); serverList.add("server2"); serverList.add("server3"); int hashCode = clientIp.hashCode(); return serverList.get(hashCode % serverList.size()); }
最小压力算法
动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能的提高后台服务器利用率,将负载合理的分流到每一台服务器