RestTemplate通过@LoadBalaced注解集成Ribbon
前言
接触过微服务的可能知道在RestTemplate
上添加@LoadBalaced
即可具备服务发现与负载均衡的能力,但是其中的原理是什么?我曾带着这样的疑问开始了一波学习。
如果对于Ribbon使用不了解的可以参考这篇文章:Ribbon的简单使用
疑问:
- 为什么RestTemplate上加一个@LoadBalaced注解即具备服务发现与负载均衡的能力?
- 为什么通过@Qualifier就能注入具有负载均衡能力的RestTemplate?
首先先说第二个问题:
当存在两个RestTemplate时,想要获取具有负载均衡能力的RestTemplate需要加@Qualifier,如下:
@Bean // 不具备负载均衡能力
public RestTemplate restTemplate() {
return new RestTemplate();
}
@LoadBalanced // 具备负载均衡能力
@Bean
public RestTemplate loadBalanceRestTemplate() {
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate; // 不具备负载均衡能力
@Qualifier
@Autowired
private RestTemplate loadBalanceRestTemplate; // 具备负载均衡能力
@Qualifier是Spring的注解,通过它可以注入同类别的Bean。而@LoadBalaced中的实现是这样的:
/**
* Annotation to mark a RestTemplate or WebClient bean to be configured to use a
* LoadBalancerClient.
* @author Spencer Gibb
*/
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}
同样使用了@Qualifier标注,所以加了@LoadBalanced注解的RestTemplate与@Qualifier的可以当作是同一种RestTemplate Bean。
自定义注解时也可以使用此方式来扩展功能:比如在自定义注解上加@Component,那么被自定义注解标记的也会被注册成Bean。
再来说第一个问题:
为什么RestTemplate上加一个@LoadBalaced注解即具备服务发现与负载均衡的能力?
- LoadBalancerAutoConfiguration
- 该类中,当存在
@LoadBalanced
的RestTemplate
时,会将bean通过@Autowired
注入到一个list中,
并且是有@LoadBalanced
标记的RestTemplate。@LoadBalanced
上有@Qualifier
标记,按类型注入。
- 在
loadBalancedRestTemplateInotializerDeprecated
方法中,对所有注入的RestTemplate
进行处理customizer.customize(restTemplate);
- 其中一个
RestTemplateCustomizer
Bean为RestTemplate
添加拦截器LoadBalancerInterceptor
或RetryLoadBalancerInterceptor
,在请求时会生成一个InterceptingClientHttpRequest,
会进入LoadBalancerInterceptor
/RetryLoadBalancerInterceptor
的intercept方法,调用RibbonLoadBalancerClient
的execute方法,执行请求。 RibbonLoadBalancerClient
借助ILoadBalancer
可达到服务发现的功能
- 该类中,当存在