Ribbon核心工作原理

1、从前面Ribbon使用(应用间通信方式HTTP和RPC, 负载均衡器 Ribbion),只需要增加LoadBalanced就能实现负载均衡。进入LoadBalanced的源码

通过注解的注释,我们知道注解标注了RestTemplate作为负载均衡客户端。负载均衡客户端接口为LoadBalancerClient
2、进入LoadBalancerClient
/**
* Represents a client-side load balancer.
*
* @author Spencer Gibb
*/
public interface LoadBalancerClient extends ServiceInstanceChooser {
<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
<T> T execute(String serviceId, ServiceInstance serviceInstance,
LoadBalancerRequest<T> request) throws IOException;
URI reconstructURI(ServiceInstance instance, URI original);
}
LoadBalancerClient继承了ServiceInstanceChooser 接口
/**
* Implemented by classes which use a load balancer to choose a server to send a request
* to.
*/
public interface ServiceInstanceChooser {
ServiceInstance choose(String serviceId);
}
1) ServiceInstance choose(String serviceId); 该方法主要是根据负载均衡器选择一个服务实例
2)<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
3)<T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException;
2) 和 3) 主要是为负载均衡器选择的服务执行请求
4)URI reconstructURI(ServiceInstance instance, URI original); 构建一个url,该方法主要使用具体逻辑服务名称作为host
3、LoadBalancerClient接口的实现类为LoadBalancerAutoConfiguration的内部类中
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({RestTemplate.class}) //当前环境有RestTemplate.class
@ConditionalOnBean({LoadBalancerClient.class}) //当前环境需要由LoadBalancerClient接口的实现类
@EnableConfigurationProperties({LoadBalancerRetryProperties.class}) //初始化复制LoadBalancerRetryProperties
public class LoadBalancerAutoConfiguration {
@LoadBalanced
@Autowired(required = false)
//@AutoWired会自动装载集合类list,会将标注了@LoadBalanced(该注解被@Qualifier注解标注)的RestTemplate添加到restTemplates中
//
private List<RestTemplate> restTemplates = Collections.emptyList();
@Autowired(
required = false
)
private List<LoadBalancerRequestTransformer> transformers = Collections.emptyList();
public LoadBalancerAutoConfiguration() {
}
@Bean
//SmartInitializingSingleton接口的实现类会在项目初始化之后被调用其afterSingletonsInstantiated方法
public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) {
return () -> {
restTemplateCustomizers.ifAvailable((customizers) -> {
Iterator var2 = this.restTemplates.iterator();
while(var2.hasNext()) {
RestTemplate restTemplate = (RestTemplate)var2.next();
Iterator var4 = customizers.iterator();
while(var4.hasNext()) {
RestTemplateCustomizer customizer = (RestTemplateCustomizer)var4.next();
customizer.customize(restTemplate);
}
}
});
};
}
@Bean
@ConditionalOnMissingBean
//LoadBalancerRequestFactory被创建
public LoadBalancerRequestFactory loadBalancerRequestFactory(LoadBalancerClient loadBalancerClient) {
return new LoadBalancerRequestFactory(loadBalancerClient, this.transformers);
}
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({RetryTemplate.class})
public static class RetryInterceptorAutoConfiguration {
public RetryInterceptorAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean
public RetryLoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient, LoadBalancerRetryProperties properties, LoadBalancerRequestFactory requestFactory, LoadBalancedRetryFactory loadBalancedRetryFactory) {
return new RetryLoadBalancerInterceptor(loadBalancerClient, properties, requestFactory, loadBalancedRetryFactory);
}
@Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer(final RetryLoadBalancerInterceptor loadBalancerInterceptor) {
return (restTemplate) -> {
List<ClientHttpRequestInterceptor> list = new ArrayList(restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
};
}
}
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({RetryTemplate.class})
public static class RetryAutoConfiguration {
public RetryAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean
public LoadBalancedRetryFactory loadBalancedRetryFactory() {
return new LoadBalancedRetryFactory() {
};
}
}
@Configuration( proxyBeanMethods = false )
@ConditionalOnMissingClass({"org.springframework.retry.support.RetryTemplate"})
static class LoadBalancerInterceptorConfig {
LoadBalancerInterceptorConfig() {
}
@Bean
//4、将loadBalancerClient接口的实现类和3方法中创建的LoadBalancerRequestFactory注入到该方法中
//同时成为LoadBalancerInterceptor的参数
public LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) {
return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
}
@Bean
@ConditionalOnMissingBean
//5、方法4中创建的LoadBalancerInterceptor会被作为参数注入进来
public RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {
return (restTemplate) -> {
//5.1 这里会在afterSingletonsInstantiated()遍历调用
List<ClientHttpRequestInterceptor> list = new ArrayList(restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
};
}
}
}
从注解中可以发现,当前类的加载时机必须存在restTemplate类,并且初始化了LoadBalancerClient的实现类。
其中LoadBalancerRequestFactory用于创建LoadBalancerRequest供LoaderBalancerInterceptor使用
LoadBalancerInterceptorConfig中维护了LoadBalancerInterceptor和RestTemplateCustomizer实例。
LoadBalancerInterceptor拦截每一次HTTP请求,将请求绑定进Ribbon负载均衡生命周期。
RestTemplateCustomizer为每个RestTemplate绑定LoadBalacerInterceptor
4、LoadBalacerInterceptor的源码如下:
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
private LoadBalancerClient loadBalancer;
private LoadBalancerRequestFactory requestFactory;
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer,
LoadBalancerRequestFactory requestFactory) {
this.loadBalancer = loadBalancer;
this.requestFactory = requestFactory;
}
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
// for backwards compatibility
this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
}
@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);
//真正的执行方法
//loadBalancer类型为LoadBalancerClient,LoadBalancerClient默认实现类为RibbonLoadBalancerClient
return this.loadBalancer.execute(serviceName,
this.requestFactory.createRequest(request, body, execution));
}
}
RibbonLoadBalancerClient的execute的源码如下
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {
return this.execute(serviceId, (LoadBalancerRequest)request, (Object)null);
}
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {
//1、根据请求的serviceId来获取具体的LoadBalanced
ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
//获得具体server(包括哪台服务器和端口号)
Server server = this.getServer(loadBalancer, hint);
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
} else {
//执行Http请求
RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);
}
}
public <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException {
Server server = null;
if (serviceInstance instanceof RibbonLoadBalancerClient.RibbonServer) {
server = ((RibbonLoadBalancerClient.RibbonServer)serviceInstance).getServer();
}
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
} else {
RibbonLoadBalancerContext context = this.clientFactory.getLoadBalancerContext(serviceId);
RibbonStatsRecorder statsRecorder = new RibbonStatsRecorder(context, server);
try {
T returnVal = request.apply(serviceInstance);
statsRecorder.recordStats(returnVal);
return returnVal;
} catch (IOException var8) {
statsRecorder.recordStats(var8);
throw var8;
} catch (Exception var9) {
statsRecorder.recordStats(var9);
ReflectionUtils.rethrowRuntimeException(var9);
return null;
}
}
}
1)首先得到一个ILoadBalancer 。ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
2)然后用它得到一个Server。 Server server = this.getServer(loadBalancer, hint);
protected Server getServer(ILoadBalancer loadBalancer, Object hint) {
return loadBalancer == null ? null : loadBalancer.chooseServer(hint != null ? hint : "default");
}
3) ZoneAwareLoadBalancer的chooseServer的代码如下
public Server chooseServer(Object key) {
if (this.counter == null) {
this.counter = this.createCounter();
}
this.counter.increment();
if (this.rule == null) {
return null;
} else {
try {
return this.rule.choose(key);
} catch (Exception var3) {
logger.warn("LoadBalancer [{}]: Error choosing server for key {}", new Object[]{this.name, key, var3});
return null;
}
}
}
这里的 this.rule.choose(key);其实就是我们定义的IRule