常见的负载均衡算法

负载均衡算法也是分布式系统中的重要组成部分,用于将来自客户端的请求分配到不同的后端服务器上,以达到提高系统吞吐量、减轻服务器负担、提高系统可用性等目的

1、轮询法

轮询法是最简单、最常见的负载均衡算法之一,其实现思路也非常简单:按照事先规定的顺序依次将请求转发至后端服务器。例如,若有4台服务器,则第1个请求会被分配到第1台服务器上,第2个请求会被分配到第2台服务器上,第3个请求会被分配到第3台服务器上,第4个请求又会被分配到第1台服务器上,以此类推

 

//定义一个全局计数器,每次调用累加
private static AtomicInteger atomicInteger = new AtomicInteger(0);
//定义服务器列表
private static List<String> serverList = new ArrayList<>();

public static String roundRobin() {
    //获取服务器数量
    int serverCount = serverList.size();
    //获取当前请求应该转发到哪台服务器
    int currentServerIndex = atomicInteger.incrementAndGet() % serverCount;
    //返回对应的服务器地址
    return serverList.get(currentServerIndex);
}

核心就在于根据服务器的数量来进行取模运算

优点:简单高效,易于水平扩展,每个节点满足字面意义上的均衡;

缺点:没有考虑机器的性能问题,根据木桶最短木板理论,集群性能瓶颈更多的会受性能差的服务器影响

2、加权轮询法

加权轮询法是在轮询法的基础上进行改进,其思路是在服务器的选择中,根据服务器的处理能力或负载情况分配不同的权重,以使处理能力较强或负载较轻的服务器获得更多的请求。例如,若存在2台服务器,其中第1台服务器负载比较重,则应当将更多的请求分配给第2台服务器

public class WeightedRoundRobinLoadBalancer {
    // 服务器列表及其服务的权重
    private static final Map<String, Integer> serverWeights = new HashMap<>();
    private static final List<String> servers = new ArrayList<>();
    // 计数器
    private static final AtomicInteger index = new AtomicInteger(0);

    public static String getNextServer() {
        int current = index.getAndIncrement();
        int serverCount = servers.size();
        // 计算权重总和
        int totalWeight =serverWeights.values().stream()
                    .mapToInt(Integer::intValue)
                    .sum();

        int currentIndex = current % totalWeight;
        // 遍历服务器列表,根据服务器权重值选择对应地址
        for (String server : servers) {
            int weight = serverWeights.get(server);
            if (currentIndex < weight) {
                return server;
            }
            currentIndex -= weight;
        }

        // unreachable code
        return null;
    }
}

优点:可以将不同机器的性能问题纳入到考量范围,集群性能最优最大化;

缺点:生产环境复杂多变,服务器抗压能力也无法精确估算,静态算法导致无法实时动态调整节点权重,只能粗糙优化

3、随机法

随机法是指将请求随机分配至后端服务器的负载均衡算法。该算法实现简单,但分配效果不可控,难以保证后端服务器的负载均衡。因此,随机法通常被用作测试或压力测试等临时场景下的负载均衡算法

//定义服务器列表
private static List<String> serverList = new ArrayList<>();

public static String random() {
    //获取服务器数量
    int serverCount = serverList.size();
    //如果没有可用的服务器返回null
    if (serverCount == 0) {
        return null;
    }
    //生成一个随机数
    int randomIndex = new Random().nextInt(serverCount);
    //返回对应的服务器地址
    return serverList.get(randomIndex);
}

 优缺点和轮询相似

4、加权随机法

加权随机法是在随机法的基础上进行改进,其思路是在服务器的选择中,根据服务器的处理能力或负载情况分配不同的权重,以使处理能力较强或负载较轻的服务器获得更多的请求

(代码参考加权轮询即可)

5、源地址哈希法

源地址哈希算法就是使用客户端 IP 地址作为哈希键。负载均衡器将哈希值映射到可用服务器中的一个,然后将请求发送到这个服务器处理。如果客户端 IP 地址发生改变(比如重启后重新分配 IP 地址),那么将会被分配到其他服务器上

//定义服务器列表
private static List<String> serverList = new ArrayList<>();

public static String hash(String clientIP) {
    //获取服务器数量
    int serverCount = serverList.size();
    //如果没有可用的服务器返回null
    if (serverCount == 0) {
        return null;
    }
    //将客户端IP地址进行哈希计算
    int hashCode = clientIP.hashCode();
    //根据哈希值计算需要转发到哪台服务器上
    int serverIndex = hashCode % serverCount;
    //返回对应的服务器地址
    return serverList.get(serverIndex);
}

优点:可以避免某些客户端被重定向到不同的服务器,对于同一IP地址的请求,总是会被分配到同一台服务器上,因此可以在一定程度上提高缓存命中率等性能指标,

缺点:如果有很多请求来自相同的 IP 地址,那么可能会导致某个服务器负载过高。另外,由于服务器数量的变化,哈希值映射也会发生变化,这可能会导致缓存无效,并且需要重新分配所有请求

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值