新闻资讯
Java 实现6种负载均衡算法
1、完全随机算法
缺点:所有服务器的访问概率都是相同的。
package com.example.demo.core.random; import java.util.Arrays; import java.util.List; import java.util.Random; /** * 负载均衡算法 * 完全随机算法 */ public class RandomServer { public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888"); static Random random = new Random(); public static String getServer() { int number = random.nextInt(list.size()); return list.get(number); } public static void main(String[] args) { for(int i = 0; i < 15; i++) { System.out.println(getServer()); } } }
2、加权随机算法
场景:有的服务器性能高,可以让随机到此服务器的可能性增大
在这里小编建了一个前端学习交流扣扣群:132667127,我自己整理的最新的前端资料和高级开发教程,如果有想需要的,可以加群一起学习交流
缺点:权重低的服务器可能很长一段时间都访问不到3
package com.example.demo.core.random; import java.util.*; /** * 负载均衡算法 * * 如果某一台服务器性能比较高,设置访问的权重高一点 * * 加权随机算法 */ public class WeightRandomServer { public static Map<String,Integer> map = new HashMap<>(); static { map.put("10.180.11.126:8888",2); map.put("10.180.11.128:8888",7); map.put("10.180.11.130:8888",1); } static Random random = new Random(); /** * 当权重设置过大时,list容易被撑爆 * @return */ public static String getServer() { List<String> list = new ArrayList<>(); for(Map.Entry<String,Integer> entry: map.entrySet()) { //根据权重,决定向list中添加几次 for(int i = 0; i < entry.getValue(); i++) { list.add(entry.getKey()); } } //list的大小 int weight = map.values().stream().mapToInt(p -> p).sum(); int number = random.nextInt(weight); return list.get(number); } /** * 优化后 * @return */ public static String getServer1() { //计算总权值 int weight = map.values().stream().mapToInt(p -> p).sum(); //随机一个随机数 int index = random.nextInt(weight); //遍历 服务 map for(Map.Entry<String,Integer> entry : map.entrySet()) { //如果权重大于 索引 if(entry.getValue() >= index) { // 返回这个服务 return entry.getKey(); } //否则,索引 = 当前索引 - 当前服务的权重 index = index - entry.getValue(); } return ""; } public static void main(String[] args) { for(int i = 0; i < 15; i++) { //System.out.println(getServer()); System.out.println(getServer1()); } } }
3、完全轮询算法
缺点:从头到尾轮询一遍,不能根据服务器性能设置权重
package com.example.demo.core.poll; import java.util.Arrays; import java.util.List; /** * 完全轮询算法 */ public class PollServer { public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888"); static int index; public static String getServer() { if(index == list.size()) { index = 0; } return list.get(index++); } public static void main(String[] args) { for(int i = 0; i < 15; i++) { System.out.println(getServer()); } } }
4、加权轮询算法
有点:可以根据服务器性能设置访问权重
缺点:可能某个服务器权重大,长时间执行,遇到耗时大的请求,压力会很大
package com.example.demo.core.poll; import java.util.HashMap; import java.util.Map; /** * 加权轮询算法 * 实际中可能遇到某个服务器压力较大,长时间执行。 */ public class WeightPollServer { public static Map<String,Integer> map = new HashMap<>(); static { map.put("10.180.11.126:8888",2); map.put("10.180.11.128:8888",7); map.put("10.180.11.130:8888",5); } static int index; public static String getServer() { int weight = map.values().stream().mapToInt( p -> p).sum(); int number = (index++) % weight; for(Map.Entry<String,Integer> entry : map.entrySet()) { if(entry.getValue() >= number) { return entry.getKey(); } number = number - entry.getValue(); } return ""; } public static void main(String[] args) { for(int i = 0; i < 15; i++) { System.out.println(getServer()); } } }
5、平滑加权轮询算法
优点:根据权重分配服务,同时又保证权重低的服务可以被访问到
缺点:集群环境下,同一个用户访问无法分流到固定一台机器
package com.example.demo.core.smooth; /** * 平滑加权 */ public class SmoothWeight { private int weight; private int currentWeight; private String address; public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } public int getCurrentWeight() { return currentWeight; } public void setCurrentWeight(int currentWeight) { this.currentWeight = currentWeight; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public SmoothWeight(int weight, int currentWeight, String address) { this.weight = weight; this.currentWeight = currentWeight; this.address = address; } }
package com.example.demo.core.smooth; import java.util.HashMap; import java.util.Map; /** * 平滑加权轮询算法 */ public class SmoothWeightPollServer { public static Map<String,SmoothWeight> map = new HashMap<>(); static { map.put("10.180.11.126:8888",new SmoothWeight(5,5,"10.180.11.126:8888")); map.put("10.180.11.128:8888",new SmoothWeight(2,2,"10.180.11.128:8888")); map.put("10.180.11.130:8888",new SmoothWeight(4,4,"10.180.11.130:8888")); } public static String getServer() { SmoothWeight maxSmoothWeight = null; int weight = map.values().stream().mapToInt(SmoothWeight :: getWeight).sum(); for(Map.Entry<String,SmoothWeight> entry : map.entrySet()) { SmoothWeight currentSmoothWeight = entry.getValue(); if(maxSmoothWeight == null || currentSmoothWeight.getCurrentWeight() > maxSmoothWeight.getCurrentWeight()) { maxSmoothWeight = currentSmoothWeight; } } assert maxSmoothWeight != null; maxSmoothWeight.setCurrentWeight(maxSmoothWeight.getCurrentWeight() - weight); for(Map.Entry<String,SmoothWeight> entry : map.entrySet()) { SmoothWeight currentSmoothWeight = entry.getValue(); currentSmoothWeight.setCurrentWeight(currentSmoothWeight.getCurrentWeight() + currentSmoothWeight.getWeight()); } return maxSmoothWeight.getAddress(); } public static void main(String[] args) { for(int i = 0; i < 15; i++) { System.out.println(getServer()); } } }
6、哈希负载算法
package com.example.demo.core.hash; import java.util.Arrays; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; /** * hash负载算法 * 在一个集群环境下,让同一个用户的访问,分流到固定的一台机器上 */ public class HashServer { public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888"); public static String getServer(String client){ int nodeCount = 40; TreeMap<Integer,String> treeMap = new TreeMap<>(); for(String s : list) { for(int i = 0; i < nodeCount; i++) { treeMap.put((s + "address:" + i).hashCode(), s); } } SortedMap<Integer,String> sortedMap = treeMap.tailMap(client.hashCode()); Integer firstHash = (sortedMap.size() > 0) ? sortedMap.firstKey() : treeMap.firstKey(); return treeMap.get(firstHash); } public static void main(String[] args) { for(int i = 0; i < 100; i++) { System.out.println(getServer("用户:" + i + "访问")); } } }
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69940844/viewspace-2678820/,如需转载,请注明出处,否则将追究法律责任。
回复列表