[源码分析]-Ribbon(1): 7种负载均衡算法

这篇具有很好参考价值的文章主要介绍了[源码分析]-Ribbon(1): 7种负载均衡算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Ribbon是客户端负载均衡算法。

1. 顶层接口

IRule是负载均衡算法的顶层接口,定义了三个方法。

public interface IRule{
    /*
     * 根据key选择一个存活的服务器
     */

    Server choose(Object key);

    /**
     * 设置lb
     */
    void setLoadBalancer(ILoadBalancer lb);

    /**
     * 获取lb
     */
    ILoadBalancer getLoadBalancer();
}

其所有的实现类都是抽象类AbstractLoadBalancerRule的子类。AbstractLoadBalancerRule定义了lb字段。

public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware {

    /**
     * 核心属性
     */
    private ILoadBalancer lb;
        
    @Override
    public void setLoadBalancer(ILoadBalancer lb){
        this.lb = lb;
    }
    
    @Override
    public ILoadBalancer getLoadBalancer(){
        return lb;
    }      
}

2. 轮询策略

策略实现类RoundRobinRule。

就是用个自增计数器,然后对所有server进行取模。但是这里对计数器有个较好的处理,可以防止计数器的溢出。

    private int incrementAndGetModulo(int modulo) {
        for (;;) {
            int current = nextServerCyclicCounter.get();
            //下一次要访问的服务index
            int next = (current + 1) % modulo;
            //***可这操作既可以让计数器自增,还可防止溢出***
            if (nextServerCyclicCounter.compareAndSet(current, next)){
                return next;
            }
        }
    }

3. 重试策略

策略实现类RetryRule。

规定了重试时间为500ms,子策略使用轮询策略。

    public Server choose(ILoadBalancer lb, Object key) {
        //默认只能重试500ms,因此计算出截至时间戳
        long requestTime = System.currentTimeMillis();
        long deadline = requestTime + maxRetryMillis;

        Server answer = null;

        answer = subRule.choose(key);

        //如果从subRule中没有选择到server,或者server不是aclive,但还未到达截至时间,则进行重试
        if (((answer == null) || (!answer.isAlive())) && (System.currentTimeMillis() < deadline)) {

            //到达超时时间后,对发送中断信号,结束下面的while循环
            InterruptTask task = new InterruptTask(deadline - System.currentTimeMillis());

            while (!Thread.interrupted()) {
                answer = subRule.choose(key);

                //如果从subRule中没有选择到server,或者server不是aclive,但还未到达截至时间,则进行重试
                if (((answer == null) || (!answer.isAlive())) && (System.currentTimeMillis() < deadline)) {
                    /* pause and retry hoping it's transient */
                    //放弃一次cpu机会
                    Thread.yield();
                } else {
                    //选择到了server,或者超时了,则退出循环
                    break;
                }
            }
            //如果逻辑到达这里的时候,还没有超时,则取消task
            task.cancel();
        }

        if ((answer == null) || (!answer.isAlive())) {
            return null;
        } else {
            return answer;
        }
    }

4. 随机策略

策略实现类RandomRule。

获取随机值,然后用该随机值返回服务。

ThreadLocalRandom.current().nextInt(serverCount)

5. 响应时间权重策略

策略实现类WeightedResponseTimeRule。

假设有3个server,分别为A, B, C,平均响应时间是5,20,50.

那么算法如下:

(1)计算所有server的平均响应时间之和:sum = 5+20+50 = 75;

(2)计算每个server的累计权重:

    1)A:sum - 5 = 70

    2)B:70 + sum - 20 = 125

    3)C:125 + sum - 50 = 150

(3)取一个随机值[0 - 150),根据这个随机值,查看哪个server的累计权重大于该值,且最接近该值,则这个server被选中。

这里面蕴含的逻辑是,谁的响应时间最小,则它的跨度越大,就越容易被随机值选中。

6. 客户端可配置策略

策略实现类ClientConfigEnabledRoundRobinRule。

内部就是RoundRobinRule。文章来源地址https://www.toymoban.com/news/detail-533630.html

到了这里,关于[源码分析]-Ribbon(1): 7种负载均衡算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Ribbon 负载均衡策略 —— 图解、源码级解析

    🍊 Java学习:社区快速通道 🍊 深入浅出RocketMQ设计思想:深入浅出RocketMQ设计思想 🍊 绝对不一样的职场干货:大厂最佳实践经验指南 📆 最近更新:2023年6月4日 🍊 点赞 👍 收藏 ⭐留言 📝 都是我最大的动力! 通过本文你可以学习到: 常见的7种负载均衡策略思想 自旋锁

    2024年02月07日
    浏览(30)
  • 【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析

    微服务间相互调用的基础上,服务间的调用更多是以调用某多实例服务下的某个实例的形式。而这就需要用到负载均衡技术。对于开发者而言,只要通过@LoadBalance注解就开启了负载均衡。如此简单的操作底层究竟是什么样的,我想你也很想知道。 在《SpringCloud集成Eureka并实现

    2024年02月05日
    浏览(26)
  • Spring Cloud 实战 | 解密负载均衡Ribbon底层原理,包含实战源码

    专栏集锦,大佬们可以收藏以备不时之需 Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏:https://blog.csdn.net/superdangbo/category_9271502.html tensorflow专栏:https://blog.csdn.net/superdangbo/category_869

    2024年02月08日
    浏览(39)
  • 1.3 eureka+ribbon,完成服务注册与调用,负载均衡源码追踪

    本篇继先前发布的1.2 eureka注册中心,完成服务注册的内容 。 目录 环境搭建 采用eureka+ribbon的方式,对多个user服务发送请求,并实现负载均衡 负载均衡原理 负载均衡源码追踪 负载均衡策略 如何选择负载均衡策略? 饥饿加载 复制(补充) 给order模块和user模块建立独立的数

    2024年02月14日
    浏览(35)
  • Ribbon:负载均衡及Ribbon

    什么是负载均衡? 第一种轮询算法,依次遍历去执行,达到负载均衡       导入pom,在消费者服务里的pom文件导入 还要导入Eureka客户端 然后消费者服务里的yml 主启动类加上注解 在配置类上加一个注解,即可实现Ribbon的负载均衡的RestTemplate 在Controller访问那里别写死了,改

    2024年02月11日
    浏览(30)
  • Ribbon:使用Ribbon实现负载均衡

     Ribbon实现的是实线走的  建立三个数据库    复制三个提供者的项目,在三个注册中心去注册这个,服务名取一样的 最后都启动     它是轮询来调用服务列表的, 三个提供者注册在一个服务上,会在服务里,生成三个服务列表,Ribbon通过默认轮询的方式,轮流访问这三个

    2024年02月11日
    浏览(22)
  • 【ribbon】Ribbon的负载均衡和扩展功能

    参考:org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration IClientConfig:Ribbon的客户端配置,默认采用DefaultClientConfigImpl实现。 IRule:Ribbon的负载均衡策略,默认采用ZoneAvoidanceRule实现,该策略能够在多区域环境下选出最佳区域的实例进行访问。 IPing:Ribbon的实例检查策略,默认

    2024年02月15日
    浏览(26)
  • SpringCloud(3) Ribbon负载均衡,负载均衡策略,自定义负载均衡

    假设我们有一台 order-service 订单服务,两台 user-service 用户服务,当订单服务需要调用用户服务获取用户信息的时候,应该怎么分配调用哪台服务呢? 这时候就需要用到 Ribbon 组件了。 首先,我们发起远程调用的时候,指定的是需要调用的服务名称,然后我们会调用 Ribbon 组

    2024年02月11日
    浏览(36)
  • 自定义负载均衡(Ribbon)

    修改配置文件 application.yml

    2024年02月02日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包