什么是Ribbon
Ribbon是Netflix发布的负载均衡器。属于SpringCloud组件之一,用于实现客户端负载均衡功能。
服务器端负载均衡
所谓服务器端负载均衡,⽐如Nginx、F5这些,请求到达服务器之后由这些负载均衡
器根据⼀定的算法将请求路由到⽬标服务器处理。
客户端负载均衡
所谓客户端负载均衡,⽐如我们要说的Ribbon,服务消费者客户端会有⼀个服务器
地址列表,调⽤⽅在请求前通过⼀定的负载均衡算法选择⼀个服务器进⾏访问,负
载均衡算法的执⾏是在请求客户端进⾏。
Ribbon的执行源码
ribbon的负载均衡是通过@LoadBalanced启动的,首先看一下LoadBalanced注解,关注一下提示被注解标记的RestTemplate bean会被配置使用LoadBalancerClient,所以我们就得到了的,主要的执行过程是在LoadBalancerClient对象中。
1 | php复制代码/** |
LoadBalancerClient
这边我把注释删除了,可以看到execute方法肯定是执行方法。
1 | java复制代码public interface LoadBalancerClient extends ServiceInstanceChooser { |
现在思考executor方法什么时候执行的?
查看引用,是在一个Interceptor方法中调用了。
RibbonLoadBalancerClient.execute
接下来看具体的execute方法
1 | scss复制代码public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException { |
getLoadBalancer方法
从一个SpringClientFactory对象获取
1 | typescript复制代码protected ILoadBalancer getLoadBalancer(String serviceId) { |
getServer方法
执行loadBalancer.chooseServer方法
1 | kotlin复制代码protected Server getServer(ILoadBalancer loadBalancer) { |
RibbonLoadBalancer.chooseServer方法
主要看else的逻辑,执行父类的chooseServer方法
1 | kotlin复制代码public Server chooseServer(Object key) { |
BaseLoadBalancer.chooseServer方法
1 | kotlin复制代码public Server chooseServer(Object key) { |
PredicateBasedRule.choose方法
主要获取server的逻辑,从loadbalancer对象中获取所有的server集合
1 | scss复制代码public Server choose(Object key) { |
以上就是ribbon的主要执行流程,接下来是具体实现细节的解答。
初始化疑问
首先在解决疑问前,要先了解ribbon的配置类,一般提前设置属性都是在初始化配置完成的。1.LoadBalancerAutoConfiguration 2.RibbonAutoConfiguration 3.RibbonClientConfiguration
疑问1.interceptor什么时候设置的?用来拦截什么对象?
这个问题是负载均衡相关的,首先定位到LoadBalancerAutoConfiguration类,具体看如下方法
1 | java复制代码public class LoadBalancerAutoConfiguration { |
所以我们知道了是在LoadBalancerAutoConfiguration类设置了拦截器,拦截restTemplate对象。
疑问2.SpringClientFactory什么时候设置的?
如下所示,SpringClientFactory是在RibbonAutoConfiguration自动配置类初始化的
1 | java复制代码... |
疑问3.LoadBalancer什么时候初始化的?Rule什么时候初始化的?
这个问题实例化就得干活儿了,涉及到需要具体实现,所以我们猜测是跟生成RibbonClient的时候有关。所以找到了RibbonClientConfiguration类,我只保留了重要代码,其他的…代替,
具体如下
1 | kotlin复制代码public class RibbonClientConfiguration { |
可以看出RibbonClientConfiguration生成了ribbon所需的所有组件,组成了ribbon服务。
疑问4.serverList什么时候加载的?
可以看到RibbonClientConfiguration生成了空的serverList对象,然后再创建loadbalancer时将这个空对象传入了。所以我们关注一下LoadBalancer初始化过程
首先调用了父类构造
1 | scss复制代码public ZoneAwareLoadBalancer(IClientConfig clientConfig, IRule rule, |
进入父类构造,属性赋值的部分就不关注了,主要关注restOfInit方法
1 | ini复制代码 public DynamicServerListLoadBalancer(IClientConfig clientConfig, IRule rule, IPing ping, |
DynamicServerListLoadBalancer.restOfInit方法
进入restOfInit方法,主要看enableAndInitLearnNewServersFeature以及updateListOfServers方法
1 | kotlin复制代码void restOfInit(IClientConfig clientConfig) { |
DynamicServerListLoadBalancer.enableAndInitLearnNewServersFeature方法
1 | java复制代码public void enableAndInitLearnNewServersFeature() { |
这边在看一下updateAction对象以及doUpdate方法,
1 | java复制代码protected final ServerListUpdater.UpdateAction updateAction = new ServerListUpdater.UpdateAction() { |
DynamicServerListLoadBalancer.updateListOfServers方法
这边就是更新服务列表的方法
1 | scss复制代码 public void updateListOfServers() { |
这边serverListImpl就是具体的注册中心客户端实现,用来向注册中心发送请求 获取服务列表
以上就是ribbon的启动以及执行流程
本文转载自: 掘金