首页 > 其他分享 >Spring Cloud LoadBalancer 如何指定服务使用指定负载均衡策略

Spring Cloud LoadBalancer 如何指定服务使用指定负载均衡策略

时间:2022-11-22 22:55:21浏览次数:45  
标签:configuration name Spring 指定 client registry metadata Cloud attrs

当系统中有多个服务A,B,C时 默认使用轮询策略 当我们A服务需要使用指定IP策略时 只需要在spring boot 代码中使用注解
@LoadBalancerClients(value = {@LoadBalancerClient(value = "A")},defaultConfiguration = IpLoadBalancerConfig.class)
就这? 没这么简单
点开@LoadBalancerClients 源码可以看到

@Configuration(proxyBeanMethods = false)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@Documented
@Import(LoadBalancerClientConfigurationRegistrar.class)
public @interface LoadBalancerClients {

	LoadBalancerClient[] value() default {};

	/**
	 * {@link LoadBalancerClientConfigurationRegistrar} creates a
	 * {@link LoadBalancerClientSpecification} with this as an argument. These in turn are
	 * added as default contexts in {@link LoadBalancerClientFactory}. Configuration
	 * defined in these classes are used as defaults if values aren't defined via
	 * {@link LoadBalancerClient#configuration()}
	 * @return classes for default configurations
	 */
	Class<?>[] defaultConfiguration() default {};

}

LoadBalancerClients 注解上有使用 @Import(LoadBalancerClientConfigurationRegistrar.class) 注解倒入一个配置类 该类实现了ImportBeanDefinitionRegistrar�接口 spring 在加载该类时 会主动调用该接口 registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry)� 用来注册bean

	public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
		Map<String, Object> attrs = metadata.getAnnotationAttributes(LoadBalancerClients.class.getName(), true);
		if (attrs != null && attrs.containsKey("value")) {
			AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value");
			for (AnnotationAttributes client : clients) {
				registerClientConfiguration(registry, getClientName(client), client.get("configuration"));
			}
		}
		if (attrs != null && attrs.containsKey("defaultConfiguration")) {
			String name;
			if (metadata.hasEnclosingClass()) {
				name = "default." + metadata.getEnclosingClassName();
			}
			else {
				name = "default." + metadata.getClassName();
			}
			registerClientConfiguration(registry, name, attrs.get("defaultConfiguration"));
		}
		Map<String, Object> client = metadata.getAnnotationAttributes(LoadBalancerClient.class.getName(), true);
		String name = getClientName(client);
		if (name != null) {
			registerClientConfiguration(registry, name, client.get("configuration"));
		}
	}

查看imput导入的类发现 registerBeanDefinitions 第一个参数返回的是LoadBalancerClients 注解 获取到使用的注解信息时 那么就可以BeanDefinitionRegistry 中 进行注册bean 信息 registerClientConfiguration(registry, name, client.get("configuration"));

	private static void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,
			Object configuration) {
		BeanDefinitionBuilder builder = BeanDefinitionBuilder
				.genericBeanDefinition(LoadBalancerClientSpecification.class);
		builder.addConstructorArgValue(name);
		builder.addConstructorArgValue(configuration);
		registry.registerBeanDefinition(name + ".LoadBalancerClientSpecification", builder.getBeanDefinition());
	}

BeanDefinitionBuilder构建了一个LoadBalancerClientSpecification的BeanDefinition 并向该类的构造方法中指定了两个参数 服务名称以及 配置类 openfeign初始化时会从LoadBalancerClientSpecification 中获取

如果发现 每次我们发现 修改一个服务的选取策略需要去修改代码 就很麻烦 那么我们是否可以 通过配置文件来修改服务的选取策略 答案是当然可以的
我们只需要增加一个配置类 实现 BeanDefinitionRegistryPostProcessorEnvironmentAware 接口则可以
EnvironmentAware 接口 会返回程序中所有配置信息 nacos,啊菠萝里的也可以 只需要在BeanDefinitionRegistryPostProcessor 的接口方法中解析出配置 构建LoadBalancerClientSpecification的BeanDefinition 就可以了

具体的后续在写

标签:configuration,name,Spring,指定,client,registry,metadata,Cloud,attrs
From: https://www.cnblogs.com/yangqifang/p/16916790.html

相关文章

  • Spring Security笔记
    这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战SpringSecurity简介SpringSecurity是一种高度自定义的安全框架,利用(基于)SpringIOC/DI和AOP功能,为系统......
  • 基于springboot和vue的IT内部电脑报修服务系统设计与实现-计算机毕业设计源码+LW文档
    it内部设备服务系统设计与实现摘要it内部设备服务系统将传统的网络服务方式与最新的互联网技术相结合,使用方便快捷,有利于设备维修部门规范管理,提高网络维修部门的工作效......
  • 基于springboot“漫画之家”系统设计与实现-计算机毕业设计源码+LW文档
    摘要随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各......
  • Spring Data(数据)Redis
    版本3.0.0SpringDataRedis项目通过使用键值样式数据存储将核心Spring概念应用于解决方案的开发。我们提供了一个“模板”作为发送和接收消息的高级抽象。您可能会注......
  • Spring Data(数据)R2DBC
    版本3.0.0SpringDataR2DBC项目将Spring的核心概念应用于开发使用关系数据库R2DBC​驱动程序的解决方案。我们提供了用于存储和查询行的高级抽象。​​DatabaseClient​......
  • 关于Spring注解的基础详解(补充上次并不清楚的内容)
    注解,需要在.xml文件里面加这么一句话:<context:component-scanbase-package=""/>(组件)Component注解主要用于接口的实现类里面,代替掉.xml文件里面的这句话:(主要作用:代替......
  • 再次打开Spring界面,多处报错
    分享一下经历在我再次打开Srpring之后,打算解决一下“历史遗留问题”,发现多处标红(挺崩溃的)!就比如这句话,刚才就是不亮:毕竟我上次的应用还是很顺利的,所以也就没有第一时间......
  • SpringMVC乱码
    <!--配置中文乱码过滤器--><filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.......
  • 数组操作 (增加删除修改遍历)map、filter、forEach、find的用法、二维数组,排序,求和、指
    一、数组的操作Array.push()->在数组后面继续插入内容Array.pop()->拿走数组最后一个内容Array…shift()->拿走数组的第一个内容(unshift也是拿走最后一个)Array.revers......
  • Spring事务的底层原理
    1.划分处理单元——IOC由于spring解决的问题是对单个数据库进行局部事务处理的,具体的实现首相用spring中的IOC划分了事务处理单元。并且将对事务的各种配置放到了ioc容......