cloud server ribbon 自定义策略配置

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

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

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

其中 serviceId 为具体服务名

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

 

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

引入关键类 RibbonClientConfiguration

?
1
2
3
4
5
6
7
8
9
10
     @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类

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

getClassName 具体实现如下:

?
1
2
3
4
5
6
7
8
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是啥呢

?
1
2
3
4
5
6
7
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类

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

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

NAMESPACE 为 ribbon

classNameProperty 为 NFLoadBalancerRuleClassName

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

 

接着看ribbonRule 第二行代码

 

?
1
<strong> return this </strong>.propertiesFactory.get(IRule.<strong> class </strong>, config, name);

具体get实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
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 ;
     }</c></c>

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

 

 

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

怎么处理呢?

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

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

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

loadbalanced.services = service-A,service-B

另外添加一个RibbonLoadBalancerRuleConfiguration类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@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);
             }
         }
     }
 
}</string>

 

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值