客户端负载均衡器——Ribbon

本文详细介绍了Ribbon作为客户端负载均衡器的工作原理,包括如何与RestTemplate结合,Ribbon的自动装配,以及负载均衡的实现过程。通过RibbonLoadBalancerClient和ILoadBalancer接口,结合ZoneAwareLoadBalancer的轮询策略,实现服务实例的选择。
摘要由CSDN通过智能技术生成

客户端负载均衡器——Ribbon

工作中的项目逐渐切换成Spring cloud微服务化。服务之间的调用是采用Ribbon+RestTemplate来实现。使用过程中踩了几次坑,查看过几次源码,所以决定进行一次比较深入的整理解析。主要是分析Ribbon是如何自动装配以及实现服务发现和负载均衡的。如有错误还望指正。

简介

ribbon一般搭配RestTemplate提供服务消费能力。ribbo为RestTemplate提供了负载均衡能力。

  • 以下源码使用spring cloud版本为:Edgware.RELEASE
  • spring-cloud-starter-hystrix:1.4.0.RELEASE,其中ribbon部分的源码是spring-cloud-commons:1.3.0.RELEASE

引入方式

一般通过在为spring装配RestTemplate时添加@LoadBalanced来引入ribbon

@Bean
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder, ClientHttpRequestFactory clientHttpRequestFactory) {
    return restTemplateBuilder.requestFactory(clientHttpRequestFactory).build();
}

使用方式

@Autowired
private RestTemplate restTemplate;

public Customer getByCustomerId(int customerId) {
    String url = "http://customer-application/customer";
    
    ParameterizedTypeReference<Customer> responseType = new ParameterizedTypeReference<Customer>(){}
    
    HttpEntity<String> requestEntity = new HttpEntity<>(body, setApplicationJsonUtf8(getHttpHeaders()));
    
    Customer customer = restTemplate.exchange(url, HttpMethod.GET, requestEntity, responseType, customerId);
    return customer;

}

如以上代码,customer-application为已经注册到Eurka上的用户服务的服务名。使用Ribbon可以将customer-application转换为实际提供服务的host:port(如10.1.23.4:7010),并可以在多个customer-application服务中进行负载均衡。

实现RestTemplate添加Ribbon源码解析

使用Ribbon只需要添加@LoadBalanced,查看其源码

/**
 * Annotation to mark a RestTemplate bean to be configured to use a LoadBalancerClient
 * @author Spencer Gibb
 */
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}

可以看到,源码注释中说明该注解用来标记一个RestTemplate配置使用LoadBalancerClient。

该注解中使用了@Qualifier注解,@Qualifier可以和@Autowire搭配使用,在一组相同的类实例中指定注入特定的实例。如:

@Bean("user1")
@Qualifier("a1")
User user1() {
    return new User(1, "a");
}

@Bean("user2")
@Qualifier("b2")
User user2() {
    return new User(2, "b");
}

@Autowired
@Qualifier("a1")
private List<User> list = new ArrayList<>();

@Autowired
@Qualifier("b2")
private Map<String,User> map = new HashMap<>();

以上代码中,list中只注入了user1,map代码中只注入了user2。

全局搜索@LoadBalanced注解,发现只在LoadBalancerAutoConfiguration中有使用,查看源码。

@Configuration
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration {

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

	@Bean
	public SmartInitializingSingleton loadBalancedRestTemplateInitializer(
			final List<RestTemplateCustomizer> customizers) {
		return new SmartInitializingSingleton() {
			@Override
			public void afterSingletonsInstantiated() {
				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) {
		ret
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值