【SpringCloud负载均衡】【源码+图解】【二】LoadBalancer配置

【SpringCloud负载均衡】【源码+图解】【一】LoadBalancer的HelloWorld体验

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拦截,然后实现负载均衡。

未完待续

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值