如果服务器的处理性能有高低的话,这时候就需要加权随机算法。加权随机算法也很简单,主要有两种形式:
一种很简单的形式是按照服务器的权重,增大服务器列表中的个数。比如服务器A的权重是7,服务器B的权重是3,那么服务器列表中就添加7个A服务器,添加3个B服务器。这时候进行随机算法的话,就会有加权的效果了。
public class ServerIps {
public static final Map<String, Integer> WEIGHT_LIST = new LinkedHashMap<>();
static {
// 权重(优先级)机器性能好的处理更多请求
// 权重之和是50
WEIGHT_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放进list
ArrayList<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 {
// 权重(优先级)机器性能好的处理更多请求 有序
// 权重之和是50
WEIGHT_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());
}
}
}