Netflix Ribbon 随机策略 RandomRule

负载均衡随机策略是一种简单直接的负载分配方法。在服务器集群环境中,当有客户端请求到达时,负载均衡器会从可用的服务器列表中随机选择一台服务器来处理该请求。这种策略不考虑服务器的当前负载情况、性能差异或其他因素,每个服务器在每次请求选择时都有相同的概率被选中。

d98ce0b9c44fd9a3c65eccb097defbe2_1728889517691-66c9d456-ae08-4fa3-9339-4005b7e19fd3_x-oss-process=image%2Fformat%2Cwebp.png

🌈注意:随机策略是无状态的。这意味着每次请求的选择过程是独立的,不依赖于之前的请求选择结果。例如,无论前一个请求被分配到了哪一台服务器,下一个请求被分配到任何一台服务器的概率仍然是相同的。这种特性使得随机策略在实现上相对简单,不需要维护复杂的服务器状态信息,如服务器的当前负载、连接数等。

配置方式

在 application.properties 中,使用如下配置:

user.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

将在名为 user 的客户端上开启随机策略。

源码分析

Ribbon 随机策略通过 com.netflix.loadbalancer.RandomRule 类实现,主要看 choose 方法:

@SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
public Server choose(ILoadBalancer lb, Object key) {
    // lb 对象中存放了服务器列表等信息
    // 如果传入的负载均衡器为null,则直接返回null,表示无法选择服务器。
    if (lb == null) {
        return null;
    } else {
        Server server = null;
        // 循环查找可用服务器
        while(server == null) {
            // 首先检查当前线程是否被中断,如果是,则返回null
            if (Thread.interrupted()) {
                return null;
            }

            // 获取可达服务器列表(upList)和所有服务器列表(allList),
            // 并获取服务器总数(serverCount)。
            List<Server> upList = lb.getReachableServers();
            List<Server> allList = lb.getAllServers();
            int serverCount = allList.size();
            // 如果服务器总数为 0,则返回 null,表示没有服务器可供选择。
            if (serverCount == 0) {
                return null;
            }

            // 使用随机数生成器(rand)生成一个随机索引,从可达服务器列表中选择一个服务器。
            int index = this.rand.nextInt(serverCount);
            server = (Server)upList.get(index);
            if (server == null) {
                // 如果选择的服务器为null,则调用Thread.yield()让出 CPU 时间片,然后继续循环尝试
                Thread.yield(); 
            } else {
                // 如果选择的服务器不为null,则检查服务器是否活着(isAlive())。
                // 如果服务器活着,则返回该服务器;
                if (server.isAlive()) {
                    return server;
                }

                // 如果服务器不活着,则将server置为null,
                // 并再次调用Thread.yield()让出 CPU 时间片,继续循环尝试。
                server = null;
                Thread.yield();
            }
        }

        return server;
    }
}

随机策略的优缺点

优点

  • 简单易实现:随机策略的实现逻辑非常直观。在代码层面,只需要一个简单的随机数生成器,根据后端服务器的数量生成一个随机索引,然后根据这个索引选择对应的服务器即可。这种简单性使得它在负载均衡系统的开发中很容易实现和理解,并且不需要复杂的算法和大量的状态维护。

  • 无状态性:每次选择服务器的过程是相互独立的,不依赖于之前的选择结果或者服务器的历史状态。这意味着不需要额外记录服务器的负载情况、连接次数等信息,减少了系统的复杂性和存储开销。

  • 一定程度的负载均衡效果:在服务器性能相近且请求分布比较均匀的情况下,随机策略能够实现一定程度的负载均衡。由于每个服务器被选中的概率相同,从长期来看,请求会相对均匀地分配到各个服务器上。这可以防止某些服务器因为长期未被选中而闲置,同时避免其他服务器过度负载,从而提高了整个服务器集群的资源利用率。

缺点

  • 负载分配不均匀:如果后端服务器的性能不一致,随机策略可能会导致性能较好的服务器负载过高,而性能较差的服务器负载不足。例如,有两台服务器,一台服务器的处理能力是另一台的两倍,但随机策略仍然以相同的概率将请求分配给它们,这就可能导致处理能力强的服务器很快达到性能瓶颈,而处理能力弱的服务器资源没有得到充分利用。

  • 缺乏适应性:随机策略不能根据服务器的实时负载、响应时间等动态因素进行调整。在系统负载发生变化或者服务器出现故障等情况下,它不能主动地将请求更多地分配到负载较轻或者正常工作的服务器上。例如,当部分服务器因为遭受攻击或者硬件故障而性能下降时,随机策略依然会按照相同的概率分配请求,可能会导致更多的请求失败或者响应延迟。

  • 不适合对顺序有要求的场景:在某些应用场景中,需要保证同一客户端的多次请求被分配到同一台服务器上,以维护会话状态或者数据一致性。随机策略无法满足这种需求,因为每次请求都独立随机选择服务器,可能会导致同一客户端的请求被分配到不同的服务器,从而破坏会话或者数据的连贯性。

适用场景

  • 服务器性能相近的场景:当后端服务器的硬件配置、软件环境以及处理能力基本相同时,随机策略是一种简单有效的负载均衡方法。

  • 对请求处理顺序无要求的场景:对于那些不需要维护会话状态或者对请求处理顺序没有严格要求的应用场景,随机策略非常适用。

  • 测试和实验环境:在测试新的应用部署或者进行性能测试实验时,随机策略可以作为一种简单的负载分配方式。

  • 资源临时性分配场景:当需要对一些临时性的资源进行负载均衡分配时,随机策略是一个不错的选择。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号