【学习记录】Spring Cloud 负载均衡之@LoadBanlance

【学习记录】Spring Cloud 负载均衡之@LoadBanlanced

RestTemplate之负载均衡

RestTemplate介绍

RestTemplate是一个用于执行 HTTP 请求的同步客户端。它是原始的 Spring REST 客户端,并通过底层 HTTP 客户端库公开了一个简单的模板方法 API。(RestTemplate官网介绍)。下方代码用于注入RestTemplate的Bean。

@Configuration
@LoadBalancerClient(value = "cloud-payment-service", configuration = RestTemplateConfig.class)
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

@LoadBanlanced注解

在RestTemplate注入时加上@LoadBanlanced注解,可以使得RestTemplate在请求服务时拥有客户端负载均衡的能力。

@Configuration
@LoadBalancerClient(value = "cloud-payment-service", configuration = RestTemplateConfig.class)
public class RestTemplateConfig {

    @Bean
    @LoadBalanced
    // 开启负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

然而为什么加上@LoadBanlanced注解后,就可以使得RestTemplate在请求服务时拥有客户端负载均衡的能力呢?
我们可以尝试追踪@LoadBanlanced注解的源码,发现该注解的源码没有有效代码,下面是@LoadBanlanced注解的源码:

package org.springframework.cloud.client.loadbalancer;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Qualifier;

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}

接下来我们来看看LoadBalancerAutoConfiguration类:

@Configuration(
    proxyBeanMethods = false
)
@Conditional({BlockingRestClassesPresentCondition.class})
@ConditionalOnBean({LoadBalancerClient.class})
@EnableConfigurationProperties({LoadBalancerClientsProperties.class})
public class LoadBalancerAutoConfiguration {
	源码过长......
}

LoadBalancerAutoConfiguration类中使用@Autowired和@LoadBanlanced注解自动注入了所有被@LoadBanlanced注解标注的RestTemplate(Bean)。

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

@Autowired注解不仅可以注入单个Bean,同时也可以注入多个Bean。仔细查看@LoadBalanced注解的源码可以发现,@LoadBanlanced注解被@Qualifier注解修饰,因此我们可以把@LoadBanlanced注解当做一个组合注解,@LoadBanlanced注解在此时拥有了@Qualifier注解的作用。在Spring框架中,当一个类需要注入多个相同类型的bean时,可以使用@Qualifier注解来指定具体的bean实例。具体例子可以阅读这篇文章(@Qualifier注解)。

	@LoadBalanced
	@Autowired(required = false)
	private List<RestTemplate> restTemplates = 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) {
                    customizer.customize(restTemplate);
                }
            }
        });
	}

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

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

	@Configuration
	@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
	static class LoadBalancerInterceptorConfig {
		@Bean
		public LoadBalancerInterceptor ribbonInterceptor(
				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);
            };
		}
	}

这段自动装配的代码含义不难理解,就是利用了RestTemplate的拦截器,使用RestTemplateCustomizer对所有标注了注解@LoadBalanced的RestTemplate(Bean)添加一个LoadBalancerInterceptor拦截器,而这个拦截器的作用就是对请求的URI进行转换,获取到具体应该请求哪个服务实例ServiceInstance。

  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值