springCloud从0开始(7)- Ribbon的源码分析

文章目录

准备

首先,启动多个服务提供者。由于当我们使用注解@LoadBanlanced标注RestTemplate类后,会导致我们通过@Autowire注入RestTemplate后,使用时全部会被ribbon拦截并进行负载均衡。

为了便于我们了解ribbon的负载均衡原理,注入其客户端LoadBalancerClient,它提供了一个choose()方法,可以根据服务名返回服务信息。因此,我增加了一个测试接口,如下:

@RestController
public class ConsumerController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @GetMapping("/testRibbonRule")
    public String testRibbonRule(String serviceName) {
        ServiceInstance serviceInstance = loadBalancerClient.choose(serviceName);
        return serviceInstance.toString();
    }
}

服务启动后,多次请求,通过返回的结果可以知道当前ribbon已经采用了轮询的策略。

源码分析

choose()方法为入口,开始对ribbon的负载均衡过程进行分析。
在这里插入图片描述
进入方法,会看到这个关键的choose()方法,通过注释可以知道,这个方法通过key选择一个Server。
在这里插入图片描述
通过方法的名字我可以看出,首先是getLoadBalancer()方法,目的应该是要获取一个负载均衡器。我们进入该方法,后面会看到方法getInstance()
在这里插入图片描述
这里得到一个AnnotationConfigApplicationContext对象,它是 Spring 框架中用于读取基于 Java 注解的配置并创建应用上下文的类。它通过扫描指定的包或类来发现带有 @Configuration、@Bean 等注解的类,并根据这些类创建应用上下文。我们进入该方法研究一下。
在这里插入图片描述
由于我是在项目刚启动后的第一次访问,容器中还没有所需的bean,因此我们发现它会在这里进行创建并注入,关键的是里面的createContext方法。进入后可以看到注入bean的逻辑。
在这里插入图片描述
通过断点可以发现他注入的类是ribbon的自动配置类。
在这里插入图片描述
继续往下,继续注册ribbon相关bean,同时向环境变量中添加了ribbon关于本次调用的服务名"provider"相关配置。
在这里插入图片描述
在这里插入图片描述
然后我们跳出这些获取context的方法,直接获取到了负载均衡器。
在这里插入图片描述
关于获取的均衡器,我们可以去看看该接口的注释,总之就是定义的标准操作。

Interface that defines the operations for a software loadbalancer. A typical loadbalancer minimally need a set of servers to loadbalance for, a method to mark a particular server to be out of rotation and a call that will choose a server from the existing list of server.
Author:
stonse

然后返回到之前的getServer()方法中
在这里插入图片描述
因为我们的hint==null,所有会选择默认方式。
继续深入方法查看,会进入到ZoneAwareLoadBalancer类中.
在这里插入图片描述
最后就进入了选择服务的负载均衡逻辑。
在这里插入图片描述
这里有一个counter,每进行一次选择就会发生增加。我们也可以去看看这个counter.increment()内部最终干了什么。counter是个BasicCounter对象,里面有个属性:count,类型为原子类型。在其increment方法中,他通过CAS的方式每次将count进行了加一操作。
然后回到调用counter.increment()的地方,我们继续查看它的选择方法。默认进入了PredicateBasedRule类的choose()方法。首先获取到了当前已注册的全部provider;
在这里插入图片描述
在这里有个关键方法chooseRoundRobinAfterFiltering,进入后发现,它首先获取了服务列表,然后通过取模的方式选择了一个服务。
在这里插入图片描述
取模的具体逻辑,我们进入方法incrementAndGetModulo查看一下。里面是一个死循环,current从0开始,每次通过CAS的方式进行加一操作并且进行取模操作。将模作为服务的下标进行返回。
最终完成了Robbon一个默认的负载均衡过程。从以上也可以确认,Ribbon的确是通过轮询的方式作为默认的负载均衡策略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Honey Ro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值