负载均衡算法

1、随机轮循算法

随机算法的实现很简单,我们可以直接通过Random的nextInt()方法实现一个加权随机算法,这种方式在日常的开发工作中还是很常用到的。

 我们首先定义一个ServerIps类,用来存放所有服务IP值

public class ServerIps {
    public static final List<String> LIST = Arrays.asList(
            "192.168.0.1",
            "192.168.0.2",
            "192.168.0.3",
            "192.168.0.4",
            "192.168.0.5",
            "192.168.0.6",
            "192.168.0.7",
            "192.168.0.8",
            "192.168.0.9",
            "192.168.0.10"
    );
}

然后我们创建类LoadBalance来实现随机算法

public class LoadBalance {
    public static String getServer(){
        Random random = new Random();
        int randomPos = random.nextInt(ServerIps.LIST.size());
        return ServerIps.LIST.get(randomPos);
    }
}

 2、加权随机轮循算法

我们生产环境上部署多台服务,可能有的机器性能好,有的机器性能较差,我们希望更多的请求能够落在性能好的机器上,而性能差的机器处理更少的请求,这个时候我们就需要使用加权随机算法来实现负载均衡,可以通过Map来实现加权

public class ServerIps {
    public static final Map<String, Integer> WEIGHT_LIST = new HashMap<>();
    static {
        WEIGHT_LIST.put("192.168.0.1",5);
        WEIGHT_LIST.put("192.168.0.2",3);
        WEIGHT_LIST.put("192.168.0.3",1);
        WEIGHT_LIST.put("192.168.0.4",6);
        WEIGHT_LIST.put("192.168.0.5",2);
        WEIGHT_LIST.put("192.168.0.6",1);
        WEIGHT_LIST.put("192.168.0.7",7);
        WEIGHT_LIST.put("192.168.0.8",1);
        WEIGHT_LIST.put("192.168.0.9",1);
        WEIGHT_LIST.put("192.168.0.10",1);
    }
}
public class LoadBalance {
    public static String getServer(){
        List<String> ips = new ArrayList<>();
        ServerIps.WEIGHT_LIST.forEach((k, v) ->{
            String ip = k;
            Integer weight = v;
            for (int i = 0;i < weight; i++){
                ips.add(ip);
            }
        });
        Random random = new Random();
        int randomPos = random.nextInt(ips.size());
        return ips.get(randomPos);
    }
}

 虽然上述代码可以实现加权随机的功能,但由于是通过在List中冗余的添加IP来实现的,会造成内存不必要的占用

 改进版:

实现思想:  例如有三台机器权重分别为[5,2,3],随机值为offset=6

[- - - - - - 5 - - 2 - - - 3]   可以想象一份空间被分为三份,

判断  offset > 5  -->  offset = offset - 5 -->  offset = 1   结论:offset不在第一份空间

判断  offset < 2   结论:offset分布在第二份空间   


public class LoadBalance {
public static String getServer(){
Integer totalWeight = 0;
for (Integer weight: ServerIps.WEIGHT_LIST.values()){
totalWeight += weight;
}

Random random = new Random();
int offset = random.nextInt(totalWeight);

for (Map.Entry<String,Integer> entry : ServerIps.WEIGHT_LIST.entrySet()){
String ip = entry.getKey();
Integer weight = entry.getValue();
if (offset < weight) {
return ip;
}
offset = offset - weight;
}
return "";
}
}
 
原文地址:https://www.cnblogs.com/chentop/p/11247766.html