ribbon的作用是负载均衡,这篇博客就来分析一下这里面的请求流程,里面贴的源码会比较多,如果看不惯的话,可以直接看最后的总结
一般来说,使用原生ribbon而不搭配feign的话,使用的都是RestTemplate,通过这个RestTemplate 来访问其他的服务,看起来是这样的
@LoadBalanced
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
RestTemplate本身并没有负载均衡的功能,只是一个单纯的http请求组件而已,通过上面的代码,我们可以发现多了一个@LoadBalanced注解,这个注解就是ribbon实现负载均衡的一个入口,我们就从这里开始看
/**
* Annotation to mark a RestTemplate 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 {
}
乍一眼看过去,这个注解好像是没啥东西,这个时候就需要一些技巧了,一般的Spring Boot项目都会有一个XXXAutoConfigration类作为自动配置类,这里面都会提供一些有用的信息,在同一个包下稍微找找就能发现一个类叫做LoadBalancerAutoConfiguration,我们接着往里面看
在这个类里面,最重要的就是给RestTemplate 添加了一个拦截器,那么这个拦截器的作用是什么呢?其实这个拦截器就是将请求交给了ribbon来处理,之后的负载均衡就由ribbon全权负责了
@Configuration
@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 new RestTemplateCustomizer() {
@Override
public void customize(RestTemplate restTemplate) {
List<ClientHttpRequestInterceptor> list = new ArrayList<>(
restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
// 将拦截器加入到restTemplate中
restTemplate.setInterceptors(list);
}
};
}
}
接下来就是看看这个拦截器具体在做些什么,首先进入这个拦截器的类,发现里面有一个intercept方法
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException