ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Ribbon的负载均衡源码

2021-09-28 01:33:11  阅读:168  来源: 互联网

标签:负载 get list incrementAndGetModulo System current 源码 Optional Ribbon


Ribbon的负载均衡

负载均衡策略

当我们发起请求的时候,把断点设置在拦截器那里,然后慢慢放行,就能来到这里,在getserver这个方法,看名字就是获取服务信息的。

image-20210928001408520

image-20210928001427269

image-20210928001457022

层层跟进发现,底层原来还是要通过IRule组件来选择服务实例的,所以这⾥依然需要确认下rule的实现类到底是谁,虽然我们可以很轻松在当前类中找到rule的默认值,如下图所示:

image-20210928003628793

因为springcloud主要还是依赖springboot,而大部分的bean的注入基本都是通过@bean注解在xxxxxConfiguration 实现的,默认为RoundBobinRule,那就去看看有没有注入别的rule组件,对其进行覆盖,结果就在 找到了。

image-20210928004135808

慢慢的往下走,发现rule的类型,确实和想的一样,然后去调用他的choose方法。

image-20210928001531183

image-20210928001625908

查看变量,确实是我们注入的2个serviceA

image-20210928002115399

getPredicate()的方法,看上去像是对server的list集合进行了过滤,因为后面的方法名字是afterFiltering,所以我们直接进去chooseRoundRobinAfterFiltering

image-20210928002220534

image-20210928002247760

发现了轮询的核心方法,注意如果在debug的模式下,负载均衡可能会有问题,我刚刚断点的时候,全是请求同一个服务实例。

下面就测试一下它核心的轮询算法:

/**
 * @author WGR
 * @create 2021/9/27 -- 21:07
 */
public class Test2 {

    static AtomicInteger nextIndex = new AtomicInteger();


    public static void main(String[] args) {
          List<String> list = new ArrayList<>();
          list.add("1");
          list.add("2");
          list.add("3");
          list.add("4");

        Optional<String> of = Optional.of(list.get(incrementAndGetModulo(list.size())));
        System.out.println(of.get());

        Optional<String> of2 = Optional.of(list.get(incrementAndGetModulo(list.size())));
        System.out.println(of2.get());

        Optional<String> of3 = Optional.of(list.get(incrementAndGetModulo(list.size())));
        System.out.println(of3.get());

        Optional<String> of4 = Optional.of(list.get(incrementAndGetModulo(list.size())));
        System.out.println(of4.get());

        Optional<String> of5 = Optional.of(list.get(incrementAndGetModulo(list.size())));
        System.out.println(of5.get());

    }

    private static int incrementAndGetModulo(int modulo) {

        for (;;) {
            int current = nextIndex.get();
            //核心的步骤就是用当前值对服务实例的总数取模,而且当前值是不断+1的。
            int next = (current + 1) % modulo;
            if (nextIndex.compareAndSet(current, next) && current < modulo)
                return current;
        }
    }

}

image-20210928002857656

但是它会有一些问题,如果我其中的一个服务挂了,它可能最多需要4分钟才能感知到,当然这个会在hystrix解决。

image-20210928010123535

标签:负载,get,list,incrementAndGetModulo,System,current,源码,Optional,Ribbon
来源: https://www.cnblogs.com/dalianpai/p/15346067.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有