总结自b站up主IT老哥视频
常见的负载均衡算法有随机、加权随机、轮询、加权轮询、平滑加权轮询、一致性哈希
public class ServerIps { public static final List<String> LIST = Arrays.asList( "A", "B", "C" ); //带权重 public static final Map<String,Integer> WEIGHT_LIST = new LinkedHashMap<String, Integer>(); static { WEIGHT_LIST.put("A",2); WEIGHT_LIST.put("B",3); WEIGHT_LIST.put("C",5); } }
//随机 public class RandomSelect { public static String getServer() { Random random = new Random(); int rand = random.nextInt(ServerIps.LIST.size()); return ServerIps.LIST.get(rand); } public static void main(String[] args) { System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); } }
public class RoundRobin { //位置 public static Integer pos = 0; public static String getServer() { String ip = null; synchronized (pos) { if(pos >= ServerIps.LIST.size()) { pos = 0; } ip = ServerIps.LIST.get(pos); pos++; } return ip; } public static void main(String[] args) { System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); } }
//缺点 权重大 ips越大 占内存 带权重随机 public class WeightRandom { public static String getServer() { //生成随机数作为List下标 List<String> ips = new ArrayList<>(); for (String ip: ServerIps.WEIGHT_LIST.keySet()) { Integer weight = ServerIps.WEIGHT_LIST.get(ip); //weight多少 在ips里面存多少 例 A 权重为2 在ips里面存两个 for (int i = 0; i < weight ; i++) { ips.add(ip); } } Random random = new Random(); int randomPos = random.nextInt(ips.size()); return ips.get(randomPos); } public static void main(String[] args) { System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); } }
执行流程:
//带权重随机 public class WeightRandomV2 { public static String getServer() { //总权重 int totalWeights = ServerIps.WEIGHT_LIST.values().stream().mapToInt(w -> w).sum(); Random random = new Random(); int pos = random.nextInt(totalWeights); for(String ip: ServerIps.WEIGHT_LIST.keySet()) { Integer weight = ServerIps.WEIGHT_LIST.get(ip); if(pos < weight) { return ip; } pos = pos - weight; } return ""; } public static void main(String[] args) { for (int i=0 ; i<10 ; i++) { System.out.println(getServer()); } } }
//缺点 权重大 ips越大 占内存 带权重轮询 public class WeightRoundRobinV0 { //被访问的次数 static int count = 0; public static String getServer() { //生成随机数作为List下标 List<String> ips = new ArrayList<>(); for (String ip: ServerIps.WEIGHT_LIST.keySet()) { Integer weight = ServerIps.WEIGHT_LIST.get(ip); //weight多少 在ips里面存多少 例 A 权重为2 在ips里面存两个 for (int i = 0; i < weight ; i++) { ips.add(ip); } } String ip = ips.get(count % ips.size()); ++count; return ip; } public static void main(String[] args) { System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); System.out.println(getServer()); } }
//轮询优化 public class WeightRoundRobin { public static String getServer(Integer num) { int totalWeights = ServerIps.WEIGHT_LIST.values().stream().mapToInt(w -> w).sum(); Integer pos = num % totalWeights; for(String ip: ServerIps.WEIGHT_LIST.keySet()) { Integer weight = ServerIps.WEIGHT_LIST.get(ip); if(pos < weight) { return ip; } pos = pos - weight; } return ""; } public static void main(String[] args) { for (int i=0 ; i<10 ; i++) { System.out.println(getServer(i)); } } }
public class WeightRoundRobinV2 { public static Map<String,Weight> currWeights = new HashMap<>(); public static String getServer() { int totalWeights = ServerIps.WEIGHT_LIST.values().stream().mapToInt(w -> w).sum(); //currentWeight 默认值 0,currentWeight初始化 if(currWeights.isEmpty()) { ServerIps.WEIGHT_LIST.forEach((ip,weight)-> { currWeights.put(ip,new Weight(ip,weight,0)); }); } //遍历动态权重,动态权重加上当前权重 for(Weight weight: currWeights.values()) { weight.setCurrentWeight(weight.getCurrentWeight() + weight.getWeight()); } //找最大值 Weight maxCurrentWeight = null; for(Weight weight: currWeights.values()) { if(maxCurrentWeight == null || weight.getCurrentWeight() > maxCurrentWeight.getCurrentWeight()) { maxCurrentWeight = weight; } } maxCurrentWeight.setCurrentWeight( maxCurrentWeight.getCurrentWeight() - totalWeights); return maxCurrentWeight.getIp(); } public static void main(String[] args) { for (int i = 0; i < 10; i++) { System.out.println(getServer()); } } }
推荐一篇通俗易懂的文章: https://www.cnblogs.com/lpfuture/p/5796398.html