Spring Cloud Ribbon源码分析(一)

一、Ribbon的作用


Spring Cloud Ribbon源码分析(一)


1,解析配置中的服务器列表



2,基于负载均衡算法来实现请求的分发


二、Ribbon做负载均衡的两种方式


1,LoadBlancerClient两种方式


Spring Cloud Ribbon源码分析(一)


2,注解方式@LoadBlancer


Spring Cloud Ribbon源码分析(一)


三、Ribbon做负载均衡的两种方式初始化


Spring Cloud Ribbon源码分析(一)


从前台代码的视角LoadBalancerClient作为入口


1,从LoadBalancerClient接口,找到其的实现类RibbonLoadBalancerClient;

2,在RibbonAutoConfiguration中,可以看到用@Bean实现RibbonLoadClient自动装配,

3,在RibbonAutoConfiguration中,同时根据@AutoConfigureBefore({LoadBalancerAutoConfiguration.class, AsyncLoadBalancerAutoConfiguration.class}),说明LoadBalancerAutoConfiguration是在RibbonAutoConfiguration之前加载的。


从@LoadBalanced的视角作为入口


1,从@LoadBalanced注解进入,发现其有@Qualifier,

在LoadBalancerAutoConfiguration中对于 @LoadBalanced private List restTemplates的自动注入,(@LoadBalanced的用法,对于A接口的实现类A1,A2,A3如果都加上@LoadBalanced;那么可以通过对List加上@LoadBalanced以及@Autowired,可以注入所有的实现类;如果对于接口A,只想注入一个类A,那么用@Qualifier(“a”)))


LoadBalancerAutoConfiguration的自动装配过程


1,通过依赖注入导入LoadBalancerInterceptor拦截器

2,RestTemplateCustomizer的作用是对修饰了@LoadBalanced注解的RestTemplate实例添加LoadBalancerInterceptor拦截器

3,SmartInitializingSingleton的作用是遍历每一个RestTemplate,用RestTemplateCustomizer定制所有被@LoadBalancer注解修饰的RestTemplate实例。

四,RestTemplate发起请求,获取IBalance以及获得Server的过程


Spring Cloud Ribbon源码分析(一)


RestTemplate发起请求的过程

1,获取负载均衡器,

2,通过负载均衡器中配置的默认负载均衡算法挑选一个合适的Server


RestTemplate.getObject()发起请求之后
1,首先会到达拦截器LoadBalancerInterceptor,调用LoadBalancerInterceptor.intercept
2,LoadBalancerClient.execute();  调用接口的execute
3,RibbonLoadBalancerClient.execute();   调用Ribbon的execute
4,获取负载均衡器 ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
5,clientFactory.getLoadBalancer(serviceId);利用工厂模式,根据serverId获取IBalanced
6,RibbonClientConfiguration自动装配中有RibbonClientConfiguration=ZoneAwareLoadBalancer 默认的轮询策略
7,RibbonLoadBalancerClient.getServer(loadBalancer, hint); 获取服务器
8,loadBalancer.chooseServer(hint != null ? hint : "default"); 选择服务器
9,BaseLoadBalancer.chooseServer();
10,rule.choose(key)
11,PredicateBasedRule.choose(key)
12,AbstractServerPredicate.chooseRoundRobinAfterFiltering(key);
13.AbstractServerPredicate.incrementAndGetModulo()默认的轮询算法 


通过上边的步骤已经得到了 server地址,重构URL


Spring Cloud Ribbon源码分析(一)


1,request.apply(serviceInstance)
2,AsyncClientHttpRequestExecution.executeAsync()
3,
4,
5,


五,前一阶段部分总结


1,首先请求会有一个拦截器,

2,拦截器怎么做到,讲到了初始化的过程,初始化是基于自动装配进行

3,初始化涉及到两个知识点,一个是@qualifer,其相当于打了个标记,这个标记针对加了LoadBalancer注解的RestTemplate进行拦截,针对需要负载均衡的RestTemplate进行拦截

4,接着拦截器的请求就会进入拦截器的方法intercept()

5,进入拦截方法后顺着调用链往下走,

6,接着获取负载均衡器,利用工厂模式根据ServerID获取ILandbalancer的实例,使用RibbonClientConfiguration自动装配获得ZoneAwareLoadBalancer

7,将获得的ZoneAwareLoadBalancer传入到getServer(loadblance,hint);

getServer(loadblance,hint)会调用LoadBalancer.chooseServer()

LoadBalancer.chooseServer会使用上一步得到的负载均衡器

BaseLoadBalancer.chooseServer()会调用rule.chooseServer(key);

rule.chooseServer(key),rule是在RibbonClientConfiguration自动装配获得ZoneAwareLoadRule

接着在PredicateBasedRule中调用choose,默认采用轮询算法做负载均衡,也就是在 AbstractServerPredicate中调用incrementAndGetModulo()

8,获取到server之后,最后一个阶段就是对URL进行重构

AsyncLoadBalancerInterceptor调用intercept方法


通过一系列的调用链 调用RibbonLoadBalancerClient中reconstructURI重构URL

发起异步远程调用AsyncClientHttpRequestExecution.executeAsync


Spring Cloud Ribbon源码分析(一)

上一篇:Spring Cloud Gateway


下一篇:Rabbit MQ消息队列原理(6)