ribbon源码个人笔记

        // spring-cloud-netfix-core
        //RibbonLoadBalancerClient    //ribbonClinet 具体的执行类  LoadBalancerClient  → ServiceInstanceChooser包含选择服务实例方法没用上,最终使用ILoadBalancer的子类方法
        //RibbonClientConfiguration  // 自动装载ZoneAwareLoadBalancer  负载均衡默认策略
        // RibbonLoadBa lancerContext  //上下文--包含ribbon重试相关   通过SpringClientFactory得到


        // com.netflix.ribbon:ribbon-loadbalancer
        //DynamicServerListLoadBalancer dd =  new DynamicServerListLoadBalancer();
        //ZoneAwareLoadBalancer
        // 父类ILoadBalancer → AbstractLoadBalancer → BaseLoadBalancer → DynamicServerListLoadBalancer → ZoneAwareLoadBalancer  服务器实例选择和管理策略
        // ZoneAwareLoadBalancer的chooseServer在zone数量不大于1的情况下会执行BaseLoadBalancer的chooseServer,实际由IRule的子类来执行,默认是RoundRobinRule
        // RoundRobinRule的choose来执,默认是常用的线性负载均衡策略      IRule → AbstractLoadBalancerRule → RoundRobinRule
        // IRule 有多个实现类 RoundRobinRule(线性轮休)、RetryRule(通过线性轮休重试)、RandomRule(随机)、ZoneAvoidanceRule、WeightedResponseTimeRule(响应时间权重)
        //  ClientConfigEnabledRoundRobinRule(高级策略实现) BestAvailableRule(loanBalancerStats找出最空闲,loanBalancerStats为空使用线性轮休【继承ClientConfigEnabledRoundRobinRule】)
        //PredicateBasedRule(通过实现的策略apply等来过滤,集成)  AvailabilityFilteringRule继承PredicateBasedRule(apply实现为,断路器是否打开、并发数大于阈值)  ZoneAvoidanceRule 默认实现,多区域rule
        //RibbonClientConfiguration 和  EurekaRibbonClientConfiguration 关联注入类PropertiesFactory(再议)
        //ConfigurationBasedServerList


        // org.springframework.cloud:spring-cloud-netflix-eureka-client
        //EurekaRibbonClientConfiguration 初始化ribbonServerList  触发DiscoveryEnabledNIWSServerList的obtainServersViaDiscovery通过eurekaClientProvider的EurekaClient
        //  需求方RibbonClientConfiguration初始化的时候注入了ServerList 用于给 ZoneAwareLoadBalancer实例化 severlist
        //DiscoveryManager.getInstance().shutdownComponent();  // LookupService  → EurekaClient → com.netflix.discovery.DiscoveryClient→ CloudEurekaClient
        //EurekaClientAutoConfiguration初始化了 EurekaDiscoveryClient   org.springframework.cloud.client.discovery.DiscoveryClient → EurekaDiscoveryClient


        //相关注解
        // @ConditionalOnMissingBean 作用在方法 list上,list为null返回true,否则返回false
        // @VisibleForTesting  用来测试私有private方法的注解
        // @Import

RoundRobinRule的choose的方法

public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        } else {
            Server server = null;
            int count = 0;

            while(true) {
                if (server == null && count++ < 10) {
                    List<Server> reachableServers = lb.getReachableServers();
                    List<Server> allServers = lb.getAllServers();
                    int upCount = reachableServers.size();
                    int serverCount = allServers.size();
                    if (upCount != 0 && serverCount != 0) {
                        int nextServerIndex = this.incrementAndGetModulo(serverCount);
                        server = (Server)allServers.get(nextServerIndex);
                        if (server == null) {
                            Thread.yield();
                        } else {
                            if (server.isAlive() && server.isReadyToServe()) {
                                return server;
                            }

                            server = null;
                        }
                        continue;
                    }

                    log.warn("No up servers available from load balancer: " + lb);
                    return null;
                }

                if (count >= 10) {
                    log.warn("No available alive servers after 10 tries from load balancer: " + lb);
                }

                return server;
            }
        }
    }


    private int incrementAndGetModulo(int modulo) {
        int current;
        int next;
        do {
            current = this.nextServerCyclicCounter.get();
            next = (current + 1) % modulo;
        } while(!this.nextServerCyclicCounter.compareAndSet(current, next));

        return next;
    }

    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }

猜你喜欢

转载自blog.csdn.net/Zzhou1990/article/details/83348417