【SpringCloud负载均衡】【源码+图解】【一】LoadBalancer的HelloWorld体验
下图是User客户端启动时配置文件的加载情况,箭头代表依赖。
// 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.LoadBalancerAutoConfigurationprivate final ObjectProvider> configurations;public LoadBalancerAutoConfiguration(ObjectProvider> configurations) {this.configurations = configurations;}// 它的作用是提供ZonePreferenceServiceInstanceListSupplier所需的zone,见4.2.2节@Bean@ConditionalOnMissingBeanpublic LoadBalancerZoneConfig zoneConfig(Environment environment) {return new LoadBalancerZoneConfig(environment.getProperty("spring.cloud.loadbalancer.zone"));}// 注入LoadBalancerClientFactory,它的作用是创建ApplicationContext并提供loadBalance所需的类,见3.2节@ConditionalOnMissingBean@Beanpublic LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties) {LoadBalancerClientFactory clientFactory = new LoadBalancerClientFactory(properties);clientFactory.setConfigurations(this.configurations.getIfAvailable(Collections::emptyList));return clientFactory;}}
@LoadBalancerClients
// 在前面的LoadBalancerAutoConfiguration之后配置
@AutoConfigureAfter(LoadBalancerAutoConfiguration.class)
@ConditionalOnClass(RestTemplate.class)
public class BlockingLoadBalancerClientAutoConfiguration {// 默认的BlockingLoadBalancerClient,它的作用是执行loadBalance的真正逻辑,见3节@Bean@ConditionalOnBean(LoadBalancerClientFactory.class)@ConditionalOnMissingBeanpublic 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);}
}
// 如果开启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@ConditionalOnMissingBeanEurekaLoadBalancerProperties eurekaLoadBalancerProperties() {return new EurekaLoadBalancerProperties();}// spring.cloud.loadbalancer.zone@Bean@ConditionalOnMissingBeanLoadBalancerZoneConfig zoneConfig(Environment environment) {return new LoadBalancerZoneConfig(environment.getProperty(LOADBALANCER_ZONE));}}
LoadBalancerInterceptorConfig是loadbalancer.LoadBalancerAutoConfiguration的内部类,按着顺序看逻辑更清晰
public class LoadBalancerAutoConfiguration {@LoadBalanced@Autowired(required = false)// 4、获取所有需要LoadBalanced的RestTemplateprivate List restTemplates = Collections.emptyList();// LoadBalancerServiceInstanceCookieTransformer// XForwardedHeadersTransformer@Autowired(required = false)private List transformers = Collections.emptyList();@Beanpublic SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(final ObjectProvider> restTemplateCustomizers) {return () -> restTemplateCustomizers.ifAvailable(customizers -> {for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {for (RestTemplateCustomizer customizer : customizers) {// 5、给每个RestTemplate添加所有装饰器的功能customizer.customize(restTemplate);}}});}@Bean@ConditionalOnMissingBeanpublic LoadBalancerRequestFactory loadBalancerRequestFactory(LoadBalancerClient loadBalancerClient) {// 1、初始化创建LoadBalancerRequest的工厂,作用是将如同http请求封装成BlockingLoadBalancerRequestreturn 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发出的请求@Beanpublic LoadBalancerInterceptor loadBalancerInterceptor(LoadBalancerClient loadBalancerClient,LoadBalancerRequestFactory requestFactory) {return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);}// 3、初始化装饰器,作用是将LoadBalancerInterceptor添加到RestTemplate@Bean@ConditionalOnMissingBeanpublic RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {return restTemplate -> {// 装饰器的功能:给restTemplate添加拦截器List list = new ArrayList<>(restTemplate.getInterceptors());list.add(loadBalancerInterceptor);restTemplate.setInterceptors(list);};}}
}
客户端成功启动后上述的配置就会生效,当客户端调用restTemplate发出请求时请求被Interceptor拦截,然后实现负载均衡。
未完待续