一、Ribbon的作用
1,解析配置中的服务器列表
2,基于负载均衡算法来实现请求的分发
二、Ribbon做负载均衡的两种方式
1,LoadBlancerClient两种方式
2,注解方式@LoadBlancer
三、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的过程
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
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