自定义ribbon负载均衡策略

虽然ribbon默认为我们提供了多钟负载均衡策略,但有时候我们仍然需要自定义符合自身业务逻辑的规则

使用配置文件的方式:我们只需要在配置文件中添加配置

    serviceId.ribbon.NFLoadBalancerRuleClassName=自定义的负载均衡策略类

其中 serviceId 为具体服务名

这样在调用对应服务时候,就会使用我们自定义的负载策略,很方便


对于该配置文件springcloud是如何解析的呢,接下来我们就分析该配置为何生效

引入关键类 RibbonClientConfiguration

        @Bean
	@ConditionalOnMissingBean
	public IRule ribbonRule(IClientConfig config) {
		if (this.propertiesFactory.isSet(IRule.class, name)) {
			return this.propertiesFactory.get(IRule.class, config, name);
		}
		ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
		rule.initWithNiwsConfig(config);
		return rule;
	}
        

第一行:判断当前环境是否设置了IRule类

public boolean isSet(Class clazz, String name) {
		return StringUtils.hasText(getClassName(clazz, name));
	}

getClassName 具体实现如下:

public String getClassName(Class clazz, String name) {
		if (this.classToProperty.containsKey(clazz)) {
			String classNameProperty = this.classToProperty.get(clazz);
			String className = environment.getProperty(name + "." + NAMESPACE + "." + classNameProperty);
			return className;
		}
		return null;
	}

而classToProperty是啥呢

public PropertiesFactory() {
		classToProperty.put(ILoadBalancer.class, "NFLoadBalancerClassName");
		classToProperty.put(IPing.class, "NFLoadBalancerPingClassName");
		classToProperty.put(IRule.class, "NFLoadBalancerRuleClassName");
		classToProperty.put(ServerList.class, "NIWSServerListClassName");
		classToProperty.put(ServerListFilter.class, "NIWSServerListFilterClassName");
	}

可以看到 其中有IRule.class对应 NFLoadBalancerRuleClassName 

回头看getClassName类 

String className = environment.getProperty(name + "." + NAMESPACE + "." + classNameProperty);

其中 name 为ribbon.client.name 也就是我们服务名,

NAMESPACE 为 ribbon

classNameProperty 为 NFLoadBalancerRuleClassName 

所以通过getClassName 方法  最终返回的是 我们系统中设置的  serviceId.ribbon.NFLoadBalancerRuleClassName 属性值


接着看ribbonRule 第二行代码

return this.propertiesFactory.get(IRule.class, config, name);

具体get实现:

public <C> C get(Class<C> clazz, IClientConfig config, String name) {
		String className = getClassName(clazz, name);
		if (StringUtils.hasText(className)) {
			try {
				Class<?> toInstantiate = Class.forName(className);
				return (C) instantiateWithConfig(toInstantiate, config);
			} catch (ClassNotFoundException e) {
				throw new IllegalArgumentException("Unknown class to load "+className+" for class " + clazz + " named " + name);
			}
		}
		return null;
	}

这样就很清晰了,最终会根据我们配置的负载策略类全路径 生成对应的实例



而我们如果一个服务需要依赖调用N多服务的时候  采用这样的配置方式,显得有点繁琐,我们的负载配置不能全局化

怎么处理呢?

当然我们可以拓展org.springframework.cloud.netflix.ribbon.PropertiesFactory类  使其支持全局配置,但springcloud官方不推荐这样处理

结合我们目前项目的处理方式,这里我给出另一条思路

在配置文件中,我们添加一个属性

loadbalanced.services = service-A,service-B

另外添加一个RibbonLoadBalancerRuleConfiguration类 

@Configuration
@ConditionalOnClass(com.netflix.loadbalancer.ZoneAvoidanceRule.class)
public class RibbonLoadbalancerRuleConfiguration implements InitializingBean {

	private final static Logger log = LoggerFactory.getLogger(RibbonLoadbalancerRuleConfiguration.class);

	
	@Value("#{'${loadbalanced.services}'.split(',')}")
	private List<String> loadbalancedServices;
	
	/**
	 * 默认使用切流量的负载均衡策略
	 */
	@Value("${ribbon.NFLoadBalancerRuleClassName}")
	private String ribbonLoadBancerRule;

	@Override
	public void afterPropertiesSet() throws Exception {
		if (null != loadbalancedServices)) {
			for (String service : loadbalancedServices)) {
				String key = service + ".ribbon.NFLoadBalancerRuleClassName";
				System.setProperty(key, ribbonLoadBancerRule);
			}
		}
	}

}

这样在配置文件中我们只需要配置

ribbon.NFLoadBalancerRuleClassName=自定义负载均衡策略
loadBalancedService=需要使用自定义负载均衡策略的服务



有时间会整理一篇更完整的ribbon负载均衡原理分析,敬请期待,,,,,,








  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Ribbon自定义负载均衡,你可以通过以下步骤进行操作: 1. 添加Ribbon依赖:在你的项目中添加Ribbon的依赖,例如使用Maven管理项目依赖的话,在`pom.xml`文件中添加如下依赖: ```xml <dependencies> ... <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> ... </dependencies> ``` 2. 创建一个自定义负载均衡器:可以实现`IRule`接口来定制自己的负载均衡策略。例如,你可以创建一个名为`CustomRule`的类来实现自己的负载均衡算法,继承自`AbstractLoadBalancerRule`。 ```java import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; public class CustomRule extends AbstractLoadBalancerRule { @Override public Server choose(Object key) { // 自定义负载均衡算法逻辑 // 返回一个Server对象作为选择结果 // 可以根据自己的需求进行算法实现 ... } } ``` 3. 配置自定义负载均衡器:在应用的配置文件中,指定使用自定义负载均衡器。例如,在`application.properties`或`application.yml`文件中添加如下配置: ``` spring: cloud: loadbalancer: ribbon: rule: com.example.CustomRule ``` 4. 启用Ribbon负载均衡:确保在应用的启动类上添加`@EnableDiscoveryClient`注解,以启用Ribbon负载均衡功能。 ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } } ``` 通过以上步骤,你就可以自定义Ribbon负载均衡策略了。注意,这里只是简单的介绍了一种实现方式,你可以根据自己的需求进行更详细的定制和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值