Ribbon调用流程
Ribbon工作原理
为什么@LoadBalanced注解能赋予RestTemplate负载均衡的能力?
Ribbon组件在启动时,会自动加载RibbonAutoConfiguration这个配置类,如下图
RibbonAutoConfiguration加载于EurekaClientAutoConfiguration之前,加载于LoadBalancerAutoConfiguration之后
引入Eureka Client必然会加载EurekaClientAutoConfiguration这个类
而RibbonAutoConfiguration中声明了这样的一个Bean,如下图:
RibbonLoadBalancerClient主要为加载LoadBalancerAutoConfiguration服务,没有RibbonLoadBalancerClient这个Bean,后者无法加载,如下图:
下面主要就来看看LoadBalancerAutoConfiguration这个类做了什么事情
首先,LoadBalancerAutoConfiguration有这样一块代码:
这块代码表示的含义是:将所有用@LoadBalanced注解标识的RestTemplate类型的Bean注入到List集合中,而恰好我们的确也声明了这样的一个Bean,如下图所示:
另外,LoadBalancerAutoConfiguration类中还有另外几块重要的代码:
public class LoadBalancerAutoConfiguration {
@Bean
public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(
final ObjectProvider<List> restTemplateCustomizers) {
return () -> restTemplateCustomizers.ifAvailable(customizers -> {
for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
for (RestTemplateCustomizer customizer : customizers) {
customizer.customize(restTemplate);
}
}
});
}
@Bean
@ConditionalOnMissingBean
public LoadBalancerRequestFactory loadBalancerRequestFactory(
LoadBalancerClient loadBalancerClient) {
return new LoadBalancerRequestFactory(loadBalancerClient, this.transformers);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
static class LoadBalancerInterceptorConfig {
@Bean
public LoadBalancerInterceptor ribbonInterceptor(
LoadBalancerClient loadBalancerClient,
LoadBalancerRequestFactory requestFactory) {
return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
}
@Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer(
final LoadBalancerInterceptor loadBalancerInterceptor) {
return restTemplate -> {
Listlist = new ArrayList<>(
restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
};
}
}
}
1)loadBalancerRequestFactory方法用于声明一个负载均衡请求生成工厂
2)LoadBalancerInterceptorConfig 这个内部静态类声明了两个Bean:
- loadBalancerInterceptor:该方法声明了一个负载均衡拦截器的Bean,该方法有两个参数loadBalancerClient、LoadBalancerRequestFactory requestFactory,这两个参数都已经有了。而LoadBalancerInterceptor继承自ClientHttpRequestInterceptor,表明LoadBalancerInterceptor就是spring boot的一个拦截器。
- restTemplateCustomizer:该方法用于声明一个RestTemplateCustomizer类型的Bean。该bean的目的在于:将RestTemplate与LoadBalancerInterceptor绑定起来,这是RestTemplate具有负载均衡能力的关键
3)loadBalancedRestTemplateInitializerDeprecated方法用于触发RestTemplateCustomizer这个Bean的执行
综上所述,RestTemplate发出的请求最后是被LoadBalancerInterceptor这个拦截器拦截到了,下面看一下LoadBalancerInterceptor的intercept方法主要做了哪些事情:
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
}
最终的请求交由loadBalancer这个负载均衡器执行,this.loadBalancer的类型是LoadBalancerClient,而LoadBalancerClient的实现为RibbonLoadBalancerClient,LoadBalancerClient继承自ServiceInstanceChooser接口
public interface ServiceInstanceChooser {
ServiceInstance choose(String serviceId);
}
通过this.loadBalancer.execute这行代码往里面跟踪,找到最终的执行方法如下(execute-1会调用execute-2):
getServer方法的实现细节:ILoadBalancer的chooseServer方法会转换为调用IRule的choose方法。ILoadBalancer和IRule是Ribbon中的两个接口
request.apply方法的实现细节:request对象是在LoadBalancerInterceptor的intercept方法中传过来的。
最后的execution.execute方法是执行最终的http请求的地方,至此,一次ribbon的生命周期就到此结束了。
标签:Spring,RestTemplate,final,Bean,源码,LoadBalancerInterceptor,LoadBalancerAutoConfig From: https://www.cnblogs.com/xfeiyun/p/17320699.html