zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    【网络流24题】方格取数问题(最大流)
    运维之思科篇——NAT基础配置
    NAT地址转换常用命令详解
    NAT(地址转换技术)详解
    Linux命令之grep用法详解:grep与正则表达式 [转]
    curl查询公网出口IP
    CentOS下安装Telnet服务
    Linux之Xinetd服务介绍
    上市公司年报发布时间是什么时候?
    jackson序列化字段字母大小写及字段名重复
  • 原文地址:https://www.cnblogs.com/dalianpai/p/15346067.html
Copyright © 2011-2022 走看看