【SpringCloud负载均衡】【源码+图解】【一】LoadBalancer的HelloWorld体验
目录
- 2. LoadBalancer的配置
- 2.1 config.LoadBalancerAutoConfiguration
- 2.2 BlockingLoadBalancerClientAutoConfiguration
- 2.3 LoadBalancerEurekaAutoConfiguration
- 2.4 loadbalancer.LoadBalancerAutoConfiguration & LoadBalancerInterceptorConfig
2. LoadBalancer的配置
下图是User客户端启动时配置文件的加载情况,箭头代表依赖。
2.1 config.LoadBalancerAutoConfiguration
// LoadBalancerClientsProperties即spring.cloud.loadbalancer.*的配置
@EnableConfigurationProperties(LoadBalancerClientsProperties.class)
// 如果不想要loadBalance功能可以将spring.cloud.loadbalancer.enabled=false,默认true,即默认开启LoadBalance功能
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.enabled", havingValue = "true", matchIfMissing = true)
public class LoadBalancerAutoConfiguration {
// 默认下是这些配置类
// default.org.springframework.cloud.netflix.eureka.loadbalancer.LoadBalancerEurekaAutoConfiguration
// org.springframework.cloud.netflix.eureka.loadbalancer.EurekaLoadBalancerClientConfiguration
// default.org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration
// default.org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration
private final ObjectProvider<List<LoadBalancerClientSpecification>> configurations;
public LoadBalancerAutoConfiguration(ObjectProvider<List<LoadBalancerClientSpecification>> configurations) {
this.configurations = configurations;
}
// 它的作用是提供ZonePreferenceServiceInstanceListSupplier所需的zone,见4.2.2节
@Bean
@ConditionalOnMissingBean
public LoadBalancerZoneConfig zoneConfig(Environment environment) {
return new LoadBalancerZoneConfig(environment.getProperty("spring.cloud.loadbalancer.zone"));
}
// 注入LoadBalancerClientFactory,它的作用是创建ApplicationContext并提供loadBalance所需的类,见3.2节
@ConditionalOnMissingBean
@Bean
public LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties) {
LoadBalancerClientFactory clientFactory = new LoadBalancerClientFactory(properties);
clientFactory.setConfigurations(this.configurations.getIfAvailable(Collections::emptyList));
return clientFactory;
}
}
2.2 BlockingLoadBalancerClientAutoConfiguration
@LoadBalancerClients
// 在前面的LoadBalancerAutoConfiguration之后配置
@AutoConfigureAfter(LoadBalancerAutoConfiguration.class)
@ConditionalOnClass(RestTemplate.class)
public class BlockingLoadBalancerClientAutoConfiguration {
// 默认的BlockingLoadBalancerClient,它的作用是执行loadBalance的真正逻辑,见3节
@Bean
@ConditionalOnBean(LoadBalancerClientFactory.class)
@ConditionalOnMissingBean
public LoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory) {
return new BlockingLoadBalancerClient(loadBalancerClientFactory);
}
// 注入LoadBalancerServiceInstanceCookieTransformer,它的作用是将配置sticky-session的信息添加到请求头,见3.5节
@Bean
@ConditionalOnBean(LoadBalancerClientFactory.class)
@ConditionalOnMissingBean(LoadBalancerServiceInstanceCookieTransformer.class)
public LoadBalancerServiceInstanceCookieTransformer loadBalancerServiceInstanceCookieTransformer(
LoadBalancerClientFactory loadBalancerClientFactory) {
return new LoadBalancerServiceInstanceCookieTransformer(loadBalancerClientFactory);
}
// 注入XForwardedHeadersTransformer,它的作用是将配置中的x-forwarded信息添加到请求头,见3.5节
@Bean
@ConditionalOnMissingBean(XForwardedHeadersTransformer.class)
@ConditionalOnBean(LoadBalancerClientFactory.class)
public XForwardedHeadersTransformer xForwarderHeadersTransformer(
LoadBalancerClientFactory loadBalancerClientFactory) {
return new XForwardedHeadersTransformer(loadBalancerClientFactory);
}
}
2.3 LoadBalancerEurekaAutoConfiguration
// 如果开启eureka客户端功能,则注入相应功能的类
@ConditionalOnProperty(name = "eureka.client.enabled", matchIfMissing = true)
public class LoadBalancerEurekaAutoConfiguration {
public static final String LOADBALANCER_ZONE = "spring.cloud.loadbalancer.zone";
// spring.cloud.loadbalancer.eureka.*的配置
@Bean
@ConditionalOnMissingBean
EurekaLoadBalancerProperties eurekaLoadBalancerProperties() {
return new EurekaLoadBalancerProperties();
}
// spring.cloud.loadbalancer.zone
@Bean
@ConditionalOnMissingBean
LoadBalancerZoneConfig zoneConfig(Environment environment) {
return new LoadBalancerZoneConfig(environment.getProperty(LOADBALANCER_ZONE));
}
}
2.4 loadbalancer.LoadBalancerAutoConfiguration & LoadBalancerInterceptorConfig
LoadBalancerInterceptorConfig是loadbalancer.LoadBalancerAutoConfiguration的内部类,按着顺序看逻辑更清晰
public class LoadBalancerAutoConfiguration {
@LoadBalanced
@Autowired(required = false)
// 4、获取所有需要LoadBalanced的RestTemplate
private List<RestTemplate> restTemplates = Collections.emptyList();
// LoadBalancerServiceInstanceCookieTransformer
// XForwardedHeadersTransformer
@Autowired(required = false)
private List<LoadBalancerRequestTransformer> transformers = Collections.emptyList();
@Bean
public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(
final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) {
return () -> restTemplateCustomizers.ifAvailable(customizers -> {
for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
for (RestTemplateCustomizer customizer : customizers) {
// 5、给每个RestTemplate添加所有装饰器的功能
customizer.customize(restTemplate);
}
}
});
}
@Bean
@ConditionalOnMissingBean
public LoadBalancerRequestFactory loadBalancerRequestFactory(LoadBalancerClient loadBalancerClient) {
// 1、初始化创建LoadBalancerRequest的工厂,作用是将如同http请求封装成BlockingLoadBalancerRequest
return new LoadBalancerRequestFactory(loadBalancerClient, this.transformers);
}
@Configuration(proxyBeanMethods = false)
// 如果org.springframework.retry.support.RetryTemplate不存在或者spring.cloud.loadbalancer.retry.enabled为false
// 默认情况下两个条件都符合,所以默认情况下走LoadBalancerInterceptor,否则走RetryLoadBalancerInterceptor
@Conditional(RetryMissingOrDisabledCondition.class)
static class LoadBalancerInterceptorConfig {
// 2、初始化拦截器LoadBalancerInterceptor,作用是拦截@LoadBalanced的RestTemplate发出的请求
@Bean
public LoadBalancerInterceptor loadBalancerInterceptor(LoadBalancerClient loadBalancerClient,
LoadBalancerRequestFactory requestFactory) {
return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
}
// 3、初始化装饰器,作用是将LoadBalancerInterceptor添加到RestTemplate
@Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {
return restTemplate -> {
// 装饰器的功能:给restTemplate添加拦截器
List<ClientHttpRequestInterceptor> list = new ArrayList<>(restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
};
}
}
}
客户端成功启动后上述的配置就会生效,当客户端调用restTemplate发出请求时请求被Interceptor拦截,然后实现负载均衡。
未完待续