如果服务器的处理性能有高低的话,这时候就需要加权随机算法。加权随机算法也很简单,主要有两种形式:
一种很简单的形式是按照服务器的权重,增大服务器列表中的个数。比如服务器A的权重是7,服务器B的权重是3,那么服务器列表中就添加7个A服务器,添加3个B服务器。这时候进行随机算法的话,就会有加权的效果了。
public class ServerIps {public static final Map<String, Integer> WEIGHT_LIST = new LinkedHashMap<>();static {// 权重(优先级)机器性能好的处理更多请求// 权重之和是50WEIGHT_LIST.put("192.168.0.1", 1);WEIGHT_LIST.put("192.168.0.2", 8);WEIGHT_LIST.put("192.168.0.3", 3);WEIGHT_LIST.put("192.168.0.4", 6);WEIGHT_LIST.put("192.168.0.5", 5);WEIGHT_LIST.put("192.168.0.6", 5);WEIGHT_LIST.put("192.168.0.7", 4);WEIGHT_LIST.put("192.168.0.8", 7);WEIGHT_LIST.put("192.168.0.9", 2);WEIGHT_LIST.put("192.168.0.10", 9);}}
public class WeightRandom {public static String getServer(){// 获取不重复的服务器ip地址Set<String> serverSet = ServerIps.WEIGHT_LIST.keySet();Iterator<String> iterator = serverSet.iterator();// 将ip放进listArrayList<String> serverList = new ArrayList<>();// 根据权重大小往新的权重服务器列表里重复添加对应的服务器while(iterator.hasNext()){String server = iterator.next();Integer weight = ServerIps.WEIGHT_LIST.get(server);for (int i = 0; i < weight; i++) {serverList.add(server);}}java.util.Random random = new java.util.Random();return serverList.get(random.nextInt(serverList.size()));}public static void main(String[] args) {for (int i = 0; i < 10; i++) {System.out.println(getServer());}}}
但是,这边也会出现一个问题,就是如果权重值很大的时候,权重服务器列表就会过大。
另一种形式是将所有权重值进行相加,然后根据这个总权重值为随机数上界,进行随机抽取服务器。比如A服务器的权重是2,B服务器的权重是3,C服务器的权重是5。总的权重值是10。在10当中取随机数。如果随机数0到2之间的话,选择A服务器,随机数在3到5之间的话,选择B服务器,随机数在5到10之间的话,选择C服务器。
这个算法,服务器地址最好是有序list,否则就会出现跳过权重小的服务器。
public class ServerIps {public static final Map<String, Integer> WEIGHT_LIST2 = new LinkedHashMap<>();static {// 权重(优先级)机器性能好的处理更多请求 有序// 权重之和是50WEIGHT_LIST2.put("192.168.0.1", 1);WEIGHT_LIST2.put("192.168.0.9", 2);WEIGHT_LIST2.put("192.168.0.3", 3);WEIGHT_LIST2.put("192.168.0.7", 4);WEIGHT_LIST2.put("192.168.0.5", 5);WEIGHT_LIST2.put("192.168.0.6", 5);WEIGHT_LIST2.put("192.168.0.4", 6);WEIGHT_LIST2.put("192.168.0.8", 7);WEIGHT_LIST2.put("192.168.0.2", 8);WEIGHT_LIST2.put("192.168.0.10", 9);}}
/*** <p>* 负载均衡加权随机算法* </p>** @author lisonglin* @version 1.0* @since 2022/5/25 13:55*/public class WeightRandomV2 {public static String getServer(){// 获取不重复的服务器ip地址// 总权重int totalWeight = 0;// 计算总权重for (int weight : ServerIps.WEIGHT_LIST2.values()) {totalWeight += weight;}java.util.Random random = new java.util.Random();// 服务器列表下标int randomWeight = random.nextInt(totalWeight);// 原理:随机权重在服务器的权重间,其实就是刚好小于这个权重值for (String ip : ServerIps.WEIGHT_LIST2.keySet()) {Integer weight = ServerIps.WEIGHT_LIST2.get(ip);if (randomWeight <= weight) {return ip;}randomWeight = randomWeight - weight;}return "";}public static void main(String[] args) {for (int i = 0; i < 10; i++) {System.out.println(getServer());}}}
