SpringCloud-Ribbon Client-初始化

loadbalancerclient

使用场景
    @GetMapping("testChoose")
    public ServiceInstance testChoose() {
     // 与Feign或RestTemplate均衡机制相同,都是基于ILoadBalancer&Rule来进行的
        return loadBalancerClient.choose("provider-app");
    }

本次基于RibbonLoadBalancerClient(在自动装配过程中,它的优先级比较高)来分析

初始化LoadBalancerClient
  // org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration

 // 用来创建Client Context, 每个ClientContext都是一个独立的上下文 
	@Bean
	public SpringClientFactory springClientFactory() {
		SpringClientFactory factory = new SpringClientFactory();
		factory.setConfigurations(this.configurations);
		return factory;
	}

 // 客户端负载均衡的入口
	@Bean
	@ConditionalOnMissingBean(LoadBalancerClient.class)
	public LoadBalancerClient loadBalancerClient() {
		return new RibbonLoadBalancerClient(springClientFactory());
	}

LoadBalancerClient的底层选择逻辑基于如下两个操作完成

       //loadbalancer init, 这是关键逻辑,超时,规则,重试都是基于此对象完成的
		ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
		// 根据LoadBalancer选择匹配的Server
		Server server = getServer(loadBalancer, hint);
ILoadBalancer的初始化
 // org.springframework.cloud.netflix.ribbon.SpringClientFactory
	/**
	 * Get the load balancer associated with the name.
	 * @param name name to search by
	 * @return {@link ILoadBalancer} instance
	 * @throws RuntimeException if any error occurs
	 */
	public ILoadBalancer getLoadBalancer(String name) {
		return getInstance(name, ILoadBalancer.class);
	}

	public SpringClientFactory() {
	   // 生成ILoadBalancer过程中会基于RibbonClientConfiguration来配置
		super(RibbonClientConfiguration.class, NAMESPACE, "ribbon.client.name");
	}
	protected AnnotationConfigApplicationContext createContext(String name) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		// 基于注解的Ribbon配置
		if (this.configurations.containsKey(name)) {
			for (Class<?> configuration : this.configurations.get(name)
					.getConfiguration()) {
				context.register(configuration);
			}
		}
		//全局 默认配置
		for (Map.Entry<String, C> entry : this.configurations.entrySet()) {
			if (entry.getKey().startsWith("default.")) {
				for (Class<?> configuration : entry.getValue().getConfiguration()) {
					context.register(configuration);
				}
			}
		}
		
		
		context.register(PropertyPlaceholderAutoConfiguration.class,
				// 默认配置模板
				this.defaultConfigType);
		context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
				this.propertySourceName,
				// 添加客户端名称
				//@Value("${ribbon.client.name}")public @interface RibbonClientName 
				// this.propertyName = ribbon.client.name
				Collections.<String, Object>singletonMap(this.propertyName, name)));
		if (this.parent != null) {
			// Uses Environment from parent as well as beans
			context.setParent(this.parent);
			// jdk11 issue
			// https://github.com/spring-cloud/spring-cloud-netflix/issues/3101
			context.setClassLoader(this.parent.getClassLoader());
		}
		context.setDisplayName(generateDisplayName(name));
		context.refresh();
		return context;
	}
基于配置文件的初始化
 // 配置读取源
	@Bean
	@ConditionalOnMissingBean
	public PropertiesFactory propertiesFactory() {
		return new PropertiesFactory();
	}

// org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration#ribbonLoadBalancer
	@Bean
	@ConditionalOnMissingBean
	public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
			ServerList<Server> serverList, ServerListFilter<Server> serverListFilter,
			IRule rule, IPing ping, ServerListUpdater serverListUpdater) {
			// 使用基于配置的初始化
		if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) {
			return this.propertiesFactory.get(ILoadBalancer.class, config, name);
		}
		return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,
				serverListFilter, serverListUpdater);
	}
`DynamicServerListLoadBalancer` 是 Netflix Ribbon 中的一个负载均衡器,用于从服务注册中心获取服务列表并进行负载均衡。 在 Spring Boot 中,可以使用 Netflix Ribbon 和 Spring Cloud Netflix 来集成该负载均衡器。 具体实现方法如下: 1. 添加 Ribbon 和 Spring Cloud Netflix 依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> ``` 2. 创建一个配置类,并指定负载均衡器的实现类 ```java @Configuration public class RibbonConfiguration { @Bean public IRule ribbonRule() { // 指定负载均衡器的实现类为 ZoneAvoidanceRule return new ZoneAvoidanceRule(); } @Bean public IPing ribbonPing() { // 指定负载均衡器的心跳检测实现类为 NoOpPing return new NoOpPing(); } } ``` 这里使用 `ZoneAvoidanceRule` 作为负载均衡器的实现类,默认情况下是使用 `RoundRobinRule`。 3. 在启动类中添加注解 `@RibbonClients` ```java @SpringBootApplication @RibbonClients(defaultConfiguration = RibbonConfiguration.class) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 这里使用 `@RibbonClients` 注解来指定 Ribbon 的配置类,即 `RibbonConfiguration`。 这样,在 Spring Boot 启动时,就会初始化 `DynamicServerListLoadBalancer`,从注册中心获取服务列表,并进行负载均衡。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值