首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringCloud @LoadBalanced 负载均衡原理

SpringCloud @LoadBalanced 负载均衡原理

原创
作者头像
用户3293499
发布2024-12-22 20:30:00
发布2024-12-22 20:30:00
2420
举报
文章被收录于专栏:微服务微服务Spring杂谈

LoadBalancerAutoConfiguration

代码里面一共有两个配置

一个是spring-cloud-common里面的org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;另外一个是 spring-cloud-loadbalancer里面的org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration

spring-cloud-common#LoadBalancerAutoConfiguration

spring-cloud-common正常是做规范用的,看package名称也能看出来,是配置客户端的,该类配置如下的bean:LoadBalancerRequestFactory,该bean用于创建请求,构造函数包含LoadBalancerClient,默认为BlockingLoadBalancerClient。另外,注册了拦截器,并获取到RestTemplate

代码语言:java
复制
public class LoadBalancerAutoConfiguration {

@LoadBalanced
@Autowired(required = false)
private List<RestTemplate> restTemplates = Collections.emptyList();

@Autowired(required = false)
private List<LoadBalancerRequestTransformer> transformers = Collections.emptyList();

/**
 * 获取@LoadBalanced注解的RestTemplate
 */
@Bean
public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(
        final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) {
    return () -> restTemplateCustomizers.ifAvailable(customizers -> {
        for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
            for (RestTemplateCustomizer customizer : customizers) {
                customizer.customize(restTemplate);
            }
        }
    });
}

@Bean
@ConditionalOnMissingBean
public LoadBalancerRequestFactory loadBalancerRequestFactory(LoadBalancerClient loadBalancerClient) {
    return new LoadBalancerRequestFactory(loadBalancerClient, this.transformers);
}

/**
 * 注册拦截器
 */
@Configuration(proxyBeanMethods = false)
@Conditional(RetryMissingOrDisabledCondition.class)
static class LoadBalancerInterceptorConfig {

    @Bean
    public LoadBalancerInterceptor loadBalancerInterceptor(LoadBalancerClient loadBalancerClient,LoadBalancerRequestFactory requestFactory) {
        return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
    }

    @Bean
    @ConditionalOnMissingBean
    public RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {
        return restTemplate -> {
            List<ClientHttpRequestInterceptor> list = new ArrayList<>(restTemplate.getInterceptors());
            list.add(loadBalancerInterceptor);
            restTemplate.setInterceptors(list);
        };
    }

}

spring-cloud-loadbalancer里面的#LoadBalancerAutoConfiguration

该配置类注册了LoadBalancerZoneConfigLoadBalancerClientFactory,后者继承了ReactiveLoadBalancer.Factory<ServiceInstance>。同时在@LoadBalancerClients中引入了LoadBalancerClientConfigurationRegistrar

LoadBalancerClientConfigurationRegistrar

用于加载配置

BlockingLoadBalancerClientAutoConfiguration

该配置类用于注册LoadBalancerClient

代码语言:java
复制
@Bean
@ConditionalOnBean(LoadBalancerClientFactory.class)
@ConditionalOnMissingBean
public LoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory) {
    return new BlockingLoadBalancerClient(loadBalancerClientFactory);
}

ReactorLoadBalancerClientAutoConfiguration

改配置有几个条件,@ConditionalOnClass(WebClient.class),@ConditionalOnBean(ReactiveLoadBalancer.Factory.class,主要用于注册 ReactorLoadBalancerExchangeFilterFunction

LoadBalancerBeanPostProcessorAutoConfiguration

用于注册LoadBalancerWebClientBuilderBeanPostProcessor,DeferringLoadBalancerExchangeFilterFunction

LoadBalancerClientConfiguration

loadbalancer客户端配置,配置了默认的负载规则,默认为轮训,还支持随机的

代码语言:java
复制
@Bean
@ConditionalOnMissingBean
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
        LoadBalancerClientFactory loadBalancerClientFactory) {
    String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
    return new RoundRobinLoadBalancer(
            loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}

若引入了nacos,则nacos会默认调整为nacos的配置

NacosLoadBalancerClientConfiguration

代码语言:java
复制
@Bean
@ConditionalOnMissingBean
public ReactorLoadBalancer<ServiceInstance> nacosLoadBalancer(Environment environment,
        LoadBalancerClientFactory loadBalancerClientFactory,
        NacosDiscoveryProperties nacosDiscoveryProperties) {
    String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
    return new NacosLoadBalancer(
            loadBalancerClientFactory.getLazyProvider(name,
                    ServiceInstanceListSupplier.class),
            name, nacosDiscoveryProperties);
}

nacos默认的机制为权重

代码语言:java
复制
ServiceInstance instance = NacosBalancer.getHostByRandomWeight3(instancesToChoose);

原理

首先获取到添加注解的RestTemplate,然后通过拦截器LoadBalancerInterceptor,进行请求拦截,并根据负责策略获取到最终的访问信息。

代码语言:java
复制
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);
		return this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
	}

}

增加了注解的resttemplate默认只能请求微服务的,此时想要支持IP+端口方式的,可以在LoadBalancerInterceptor前增加拦截器,可参考:Spring Cloud RestTemplate @LoadBalanced 支持ip、域名、服务名 调用,注意修改优先级即可

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LoadBalancerAutoConfiguration
    • spring-cloud-common#LoadBalancerAutoConfiguration
    • spring-cloud-loadbalancer里面的#LoadBalancerAutoConfiguration
      • LoadBalancerClientConfigurationRegistrar
  • BlockingLoadBalancerClientAutoConfiguration
  • ReactorLoadBalancerClientAutoConfiguration
  • LoadBalancerBeanPostProcessorAutoConfiguration
  • LoadBalancerClientConfiguration
  • 原理
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档