Ribbon 实现客户端负载均衡与LoadBalanced注解
1、@LoadBalanced 该注解用于标记项目中的RestTemplate 实例bean
2、从@LoadBalanced注解码的注释中,可以知道该注解用来给RestTemplate标记,以使用负载均衡的客户端(LoadBalancerClient)来配置它。
顺着LoadBalancerClient接口的所属包org.springframework.cloud.client.loadbalancer,我们对其内容进行整理,从类的命名上可初步判断LoadBalancerAutoConfiguration为实现客户端负载均衡器的自动化配置类。
从LoadBalancerAutoConfiguration类上的注解可知,Ribbon实现负载均衡自动化配置需要满足下面两个条件:
@ConditionalOnClass(RestTemplate.class):RestTemplate必须存在于当前工程的环境中。
@ConditionalOnBean(LoadBalancerClient.class):在Spring的Bean工程中必须有LoadBalancerClient的实现bean。
该自动配置类,主要做了下面三件事:
创建了一个LoadBalancerInterceptor的Bean,用于实现对客户端发起请求时进行拦截,以实现客户端负载均衡。
创建了一个RestTemplateCustomizer的Bean,用于给RestTemplate增加LoadbalancerInterceptor
维护了一个被@LoadBalanced注解修饰的RestTemplate对象列表,并在这里进行初始化,通过调用RestTemplateCustomizer的实例来给需要客户端负载均衡的RestTemplate增加LoadBalancerInterceptor拦截器。
接下来,我们看看LoadBalancerInterceptor拦截器是如何将一个普通的RestTemplate
org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor
通过源码以及之前的自动化配置类,我们可以看到在拦截器中注入了LoadBalancerInterceptor的实现。当一个被@LoadBalanced注解修饰的RestTemplate对象向外发起HTTP请求时,会被LoadBalancerInterceptor类的intercept函数所拦截。由于我们在使用RestTemplate时候采用了服务名作为host,所以直接从HttpRequest的URI对象中通过getHost()就可以拿到服务名,然后调用execute函数去根据服务名来选择实例并发起实际的请求。
分析到这里,LoadBalancerClient还只是一个抽象的负载均衡器接口,所以我们还需要找到它的具体实现类进一步进行分析,通过查看Ribbon的源码,可以很容易地在org.springframework.cloud.netflix.ribbon包下找到对应的实现类RibbonLoadBalancerClient。
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient
到这里基本能找到ribbon与restTemplate的负载关联了,详细可自行参阅https://www.jianshu.com/p/1bd66db5dc46