SpringCloud组件原理刨析之Ribbon

本文详细剖析了SpringCloud组件Ribbon的工作原理,包括Ribbon作为客户端负载均衡器的角色,如何与RestTemplate结合,以及Ribbon在初始化和运行阶段的逻辑。在初始化阶段,Ribbon会收集@LoadBalanced的RestTemplate并添加拦截器。在运行阶段,通过ILoadBalancer选择服务器,并使用预设的负载均衡算法如轮询进行请求分发。同时,Ribbon会定期更新服务器列表以保持服务发现的准确性。
摘要由CSDN通过智能技术生成

什么是Ribbon

Ribbon是一个提供在客户端的负载均衡的组件,相对于nginx会较轻量级。Ribbon的本质其实就是一个拦截器。相信大家都知道在使用Ribbon的时候,会和RestTemplate一起使用,在使用RestTempplate的时候,但此时的URL是一个htpp://servername/method的一个形式,所以Ribbon会在调用前,进行拦截,将Url解析成,http://ip+port的的形式,然后在进行负载均衡相关算法来分发HTTP请求。

  • 解析基于配置中的服务器列表
  • 基于负载均衡算法来分发HTTP请求

刨析Ribbon源码

我们来看这样一段代码

@Controller
public class UserController {
   

    @Autowired
    RestTemplate restTemplate;

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){
   
        return restTemplateBuilder.build();
    }
    @Autowired
    LoadBalancerClient loadBalancerClient;

    @GetMapping("/user/{id}")
    public String findById(@PathVariable("id")int id){
   
        ServiceInstance serviceInstance=loadBalancerClient.choose("spring-cloud-order-service");
        String url=String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort()+"/orders");
        return restTemplate.getForObject(url,String.class);
    }

}

由此可以看出,与常规使用restTemplate进行正常的http调用,这里只多了一个注解@LoadBalanced,那就从这个注解开始瞅瞅它的真面目。@LoadBalanced的源码是这样的:

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;

/**
 * Annotation to mark a RestTemplate or WebClient 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 {
   

}

在上面的源码中我们看到了@Qualifier这个注解了,这个注解表示一个标记的含义,由此可以得出,@loadBalanced是给RestTepmlate做了一个标记,那么我们来具体看看这个标记做了什么事。我们先搜索到LoadBalancerAutoConfiguration 这个类

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration {
   
	//自动扫描加了@LoadBalanced标注的类,进行注入
	@LoadBalanced
	@Autowired(required = false)
	private List<RestTemplate> restTemplates = Collections.emptyList();

	@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) {
   
					customizer.customize(restTemplate);
				}
			}
		});
	}

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

	@Configuration(proxyBeanMethods = false)
	@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<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值