聊聊Ribbon源码解读
Posted 周杰伦本人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊Ribbon源码解读相关的知识,希望对你有一定的参考价值。
聊聊Ribbon源码解读
要说当今最流行的组件当然是SpringCloud,要说框架中最流行的负载均衡组件,非Ribbon莫属了
@LoadBalanced注解
当我们使用Ribbon的时候,spring中注入RestTemplate,并在上边添加 @LoadBalanced,这样使用RestTemplate发送请求的时候就实现了负载均衡
@Bean
@LoadBalanced
public RestTemplate restTemplate()
return new RestTemplate();
为什么会这样呢?今天我们分析一下它是什么工作的
配置文件
我们看一下Ribbon包下的spring.factories文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration
配置类
这里显然自动装配了RibbonAutoConfiguration类,这就是入口了,我们深入这个类看一下,类上有个注解
@AutoConfigureBefore(LoadBalancerAutoConfiguration.class, AsyncLoadBalancerAutoConfiguration.class)
表示RibbonAutoConfiguration加载后加载LoadBalancerAutoConfiguration和AsyncLoadBalancerAutoConfiguration
我们先看一下LoadBalancerAutoConfiguration类,LoadBalancerAutoConfiguration注入了RestTemplateCustomizer对象,并向RestTemplateCustomizer实例中添加lanjie器LoadBalancerInterceptor,然后RestTemplate定制器RestTemplateCustomizer会向restTemplates集合中遍历每个restTemplate来添加lanjie器
lanjie器
那我们需要看一下LoadBalancerInterceptorlanjie器了,众所周知,lanjie器最重要的就是它的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));
request.getURI()会获取到相应的url,originalUri.getHost()会拿到服务名,然后调用LoadBalancerClient的execute(),那么具体是哪个LoadBalancerClient实例呢,通过RibbonAutoConfiguration的bean定义我们知道:
@Bean
@ConditionalOnMissingBean(LoadBalancerClient.class)
public LoadBalancerClient loadBalancerClient()
return new RibbonLoadBalancerClient(springClientFactory());
是RibbonLoadBalancerClient,我们看一它的execute()方法
RibbonLoadBalancerClient
RibbonLoadBalancerClient的execute()方法
@Override
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
Server server = getServer(loadBalancer);
if (server == null)
throw new IllegalStateException("No instances available for " + serviceId);
RibbonServer ribbonServer = new RibbonServer(serviceId, server, isSecure(server,
serviceId), serverIntrospector(serviceId).getMetadata(server));
return execute(serviceId, ribbonServer, request);
- 获取负载均衡器
- 使用负载均衡器来选择最终要用的Server服务
- 把Server对象封装成RibbonServer
- 调用execute()来执行
接下来我们将重点分析下负载均衡器是如何定义的,负载均衡器是怎么选择服务器和execute()方法的逻辑是怎么样的
总结
这篇文章是Ribbon源码解读的第一篇,我们从springboot的自动装配的RibbonAutoConfiguration作为入口,分析了Ribbon是如果给RestTemplate添加LoadBalancerInterceptor lanjie器的,以及lanjie器的lanjie方法中调用RibbonLoadBalancerClient的execute(),接着分析了execute()方法中先获取lanjie器,再选择服务,然后执行execute()方法
以上是关于聊聊Ribbon源码解读的主要内容,如果未能解决你的问题,请参考以下文章