Ribbon工作原理


重点:Ribbon给restTemplate添加了一个拦截器
思考:Ribbon在做什么:
当我们访问http://lagou-service-resume/resume/openstate/的时候,ribbon应该根据服务名lagou-service-resume获取到该服务的实例列表并按照一定的负载均衡策略从实例列表中获取⼀个实例Server,并最终通过RestTemplate进行请求访问。
Ribbon细节结构图(涉及到底层的⼀些组件/类的描述)

图中核心是负载均衡管理器LoadBalancer(总的协调者,相当于大脑,为了做事情,协调四肢),围绕它周围的多有IRule、IPing等
我们在RestTemplate实例上添加了一个@LoadBalanced注解,就可以实现负载均衡,很神奇,我们接下来分析这个注解背后的操作(负载均衡过程)

- public interface LoadBalancerClient extends ServiceInstanceChooser
- {
- // 根据服务执⾏请求内容
-
T execute(String serviceId, LoadBalancerRequest request) throws IOException; - // 根据服务执⾏请求内容
-
T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request) throws IOException; - // 拼接请求⽅式 传统中是ip:port 现在是服务名称:port 形式
- URI reconstructURI(ServiceInstance instance, URI original);
- }



LoadBalancerAutoConfiguration里面的内容剖析
第一处:注入resttemplate对象到集合待用

第二处:注入resttemplate定制器

第三处:使用定制器给集合中的每一个resttemplate对象添加一个拦截器

到这里,我们明白,添加了注解的RestTemplate对象会被添加一个拦截器LoadBalancerInterceptor,该拦截器就是后续拦截请求进行负载处理的。
所以,下一步重点我们该分析拦截器LoadBalancerInterceptor------>>>intercept()方法
分析LoadBalancerInterceptor.intercept()方法

那么?RibbonLoadBalancerClient对象是在哪⾥注⼊的===》》回到最初的自动配置类RibbonAutoConfiguration中

OMG! 负载均衡的事情执行原来交给了我们最初看到的RibbonLoadBalancerClient对象
非常核心的一个方法:RibbonLoadBalancerClient.execute()


回到主配置类RibbonAutoConfiguration


RibbonClientConfiguration中装配了大脑和肢干



ZoneAwareLoadBalancer#chooseServer

父类:com.netflix.loadbalancer.BaseLoadBalancer#chooseServer

来到区域隔离策略的父类choose方法中com.netflix.loadbalancer.PredicateBasedRule#choose



前文我们提到的关注点3



AbstractClientHttpRequest#execute
此处,就已经到了RestTemplate底层执行的代码了,由此也将验证最终请求的调用还是靠的RestTemplate

接下来,在进行负载chooseServer的时候,LoadBalancer负载均衡器中已经有了serverList,那么这个serverList是什么时候被注入到LoadBalancer中的,它的一个机制大概是怎样的?
来到RibbonClientConfiguration


把目光聚焦到使用这个空对象ServerList的地方




进入enableAndInitLearnNewServersFeature()方法




