如果服务器的处理性能有高低的话,这时候就需要加权随机算法。加权随机算法也很简单,主要有两种形式:
    一种很简单的形式是按照服务器的权重,增大服务器列表中的个数。比如服务器A的权重是7,服务器B的权重是3,那么服务器列表中就添加7个A服务器,添加3个B服务器。这时候进行随机算法的话,就会有加权的效果了。

    1. public class ServerIps {
    2. public static final Map<String, Integer> WEIGHT_LIST = new LinkedHashMap<>();
    3. static {
    4. // 权重(优先级)机器性能好的处理更多请求
    5. // 权重之和是50
    6. WEIGHT_LIST.put("192.168.0.1", 1);
    7. WEIGHT_LIST.put("192.168.0.2", 8);
    8. WEIGHT_LIST.put("192.168.0.3", 3);
    9. WEIGHT_LIST.put("192.168.0.4", 6);
    10. WEIGHT_LIST.put("192.168.0.5", 5);
    11. WEIGHT_LIST.put("192.168.0.6", 5);
    12. WEIGHT_LIST.put("192.168.0.7", 4);
    13. WEIGHT_LIST.put("192.168.0.8", 7);
    14. WEIGHT_LIST.put("192.168.0.9", 2);
    15. WEIGHT_LIST.put("192.168.0.10", 9);
    16. }
    17. }
    1. public class WeightRandom {
    2. public static String getServer(){
    3. // 获取不重复的服务器ip地址
    4. Set<String> serverSet = ServerIps.WEIGHT_LIST.keySet();
    5. Iterator<String> iterator = serverSet.iterator();
    6. // 将ip放进list
    7. ArrayList<String> serverList = new ArrayList<>();
    8. // 根据权重大小往新的权重服务器列表里重复添加对应的服务器
    9. while(iterator.hasNext()){
    10. String server = iterator.next();
    11. Integer weight = ServerIps.WEIGHT_LIST.get(server);
    12. for (int i = 0; i < weight; i++) {
    13. serverList.add(server);
    14. }
    15. }
    16. java.util.Random random = new java.util.Random();
    17. return serverList.get(random.nextInt(serverList.size()));
    18. }
    19. public static void main(String[] args) {
    20. for (int i = 0; i < 10; i++) {
    21. System.out.println(getServer());
    22. }
    23. }
    24. }

    但是,这边也会出现一个问题,就是如果权重值很大的时候,权重服务器列表就会过大
    另一种形式是将所有权重值进行相加,然后根据这个总权重值为随机数上界,进行随机抽取服务器。比如A服务器的权重是2,B服务器的权重是3,C服务器的权重是5。总的权重值是10。在10当中取随机数。如果随机数0到2之间的话,选择A服务器,随机数在3到5之间的话,选择B服务器,随机数在5到10之间的话,选择C服务器。
    这个算法,服务器地址最好是有序list,否则就会出现跳过权重小的服务器。

    1. public class ServerIps {
    2. public static final Map<String, Integer> WEIGHT_LIST2 = new LinkedHashMap<>();
    3. static {
    4. // 权重(优先级)机器性能好的处理更多请求 有序
    5. // 权重之和是50
    6. WEIGHT_LIST2.put("192.168.0.1", 1);
    7. WEIGHT_LIST2.put("192.168.0.9", 2);
    8. WEIGHT_LIST2.put("192.168.0.3", 3);
    9. WEIGHT_LIST2.put("192.168.0.7", 4);
    10. WEIGHT_LIST2.put("192.168.0.5", 5);
    11. WEIGHT_LIST2.put("192.168.0.6", 5);
    12. WEIGHT_LIST2.put("192.168.0.4", 6);
    13. WEIGHT_LIST2.put("192.168.0.8", 7);
    14. WEIGHT_LIST2.put("192.168.0.2", 8);
    15. WEIGHT_LIST2.put("192.168.0.10", 9);
    16. }
    17. }
    1. /**
    2. * <p>
    3. * 负载均衡加权随机算法
    4. * </p>
    5. *
    6. * @author lisonglin
    7. * @version 1.0
    8. * @since 2022/5/25 13:55
    9. */
    10. public class WeightRandomV2 {
    11. public static String getServer(){
    12. // 获取不重复的服务器ip地址
    13. // 总权重
    14. int totalWeight = 0;
    15. // 计算总权重
    16. for (int weight : ServerIps.WEIGHT_LIST2.values()) {
    17. totalWeight += weight;
    18. }
    19. java.util.Random random = new java.util.Random();
    20. // 服务器列表下标
    21. int randomWeight = random.nextInt(totalWeight);
    22. // 原理:随机权重在服务器的权重间,其实就是刚好小于这个权重值
    23. for (String ip : ServerIps.WEIGHT_LIST2.keySet()) {
    24. Integer weight = ServerIps.WEIGHT_LIST2.get(ip);
    25. if (randomWeight <= weight) {
    26. return ip;
    27. }
    28. randomWeight = randomWeight - weight;
    29. }
    30. return "";
    31. }
    32. public static void main(String[] args) {
    33. for (int i = 0; i < 10; i++) {
    34. System.out.println(getServer());
    35. }
    36. }
    37. }