虽然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负载均衡原理分析,敬请期待

cloud server ribbon 自定义策略配置的更多相关文章

  1. Spring Cloud Gateway Ribbon 自定义负载均衡

    在微服务开发中,使用Spring Cloud Gateway做为服务的网关,网关后面启动N个业务服务.但是有这样一个需求,同一个用户的操作,有时候需要保证顺序性,如果使用默认负载均衡策略,同一个用户的 ...

  2. Spring Cloud Netflix Ribbon详细介绍及自定义规则策略

    之前文章我们介绍了如何配置具有Ribbon轮询机制的负载均衡策略的消费者,这次来具体了解一下Ribbon的一些细节,以及如何自定义负载均衡策略等. 说一下Ribbon实现负载均衡的大致思路.它通过用@ ...

  3. 自定义Ribbon客户端策略

    说明   为了实现Ribbon细粒度的划分,让调用不同的微服务时采用不同的客户端负载均衡策略, 通常情况下我们会自定义配置策略.   本文以内容中心(content-center)调用户中心微服务(u ...

  4. 【SpringCloud】Ribbon如何自定义客户端配置和全局配置

    起因 事情的起因是这样的,公司内部要实现基于Zuul网关的灰度路由,在上线时进行灰度测试,故需要配置业务微服务向Eureka注册的metadata元数据,和自定义Ribbon的负载规则达到只访问灰度服 ...

  5. 笔记:Spring Cloud Feign Ribbon 配置

    由于 Spring Cloud Feign 的客户端负载均衡是通过 Spring Cloud Ribbon 实现的,所以我们可以直接通过配置 Ribbon 的客户端的方式来自定义各个服务客户端调用的参 ...

  6. Spring Cloud Feign Ribbon 配置

    由于 Spring Cloud Feign 的客户端负载均衡是通过 Spring Cloud Ribbon 实现的,所以我们可以直接通过配置 Ribbon 的客户端的方式来自定义各个服务客户端调用的参 ...

  7. 从零开始学spring cloud(六) -------- Ribbon

    一.Ribbon介绍 Ribbon就是客户端侧负责均衡实现的一种方式,那么Ribbon是什么呢? Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端侧负载均衡算法.Ribb ...

  8. SpringCloud的Ribbon自定义负载均衡算法

    1.Ribbon默认使用RoundRobinRule策略轮询选择server 策略名 策略声明 策略描述 实现说明 BestAvailableRule public class BestAvailab ...

  9. SpringCloud微服务实战——搭建企业级开发框架(三十六):使用Spring Cloud Stream实现可灵活配置消息中间件的功能

      在以往消息队列的使用中,我们通常使用集成消息中间件开源包来实现对应功能,而消息中间件的实现又有多种,比如目前比较主流的ActiveMQ.RocketMQ.RabbitMQ.Kafka,Stream ...

随机推荐

  1. APP-8-文本语音

    1.百度语音合成JS文件 baidu_tts_cors.js /** * 浏览器调用语音合成接口 * @param {Object} param 百度语音合成接口参数 * 请参考 https://ai ...

  2. 关于cordova 状态栏设置

    https://blog.csdn.net/u011127019/article/details/58104056

  3. HTML:Registry design.(Include a simple web design use HTML)

    Registry design: I feel a little bored when I design this registry,so T design a simple website all ...

  4. Delphi动态配置ODBC数据源--SQL Server版本

    (摘自)http://jxlearnew.blog.163.com/blog/static/549786592007102451431413/ 这里介绍一种用Delphi来实现动态注册的方法,希望对各 ...

  5. 收藏点webservice接口

    商业和贸易: 1.股票行情数据 WEB 服务(支持香港.深圳.上海基金.债券和股票:支持多股票同时查询) Endpoint: http://webservice.webxml.com.cn/WebSe ...

  6. iOS修改状态栏颜色

    application.statusBarStyle = .LightContent // 在APPlication中设置全局状态栏颜色,为白色 application.statusBarHidden ...

  7. 构建BSP (boardsupport packet)

    由于移植期间遇到较多头文件包含及常量定义问题,故在此总结如下: 常量定义一般涉及到寄存器定义.寄存器配置常量定义,寄存器配置常量一般在驱动目录下自定义,所以如果编译过程中出现常量未定义的情况一般是属于 ...

  8. c 语言的复杂声明

    简化的声明语法: dcl: optional *'s direct-dcl direct-dcl: name (dcl)  direct-dcl() direct-dcl[optional size] ...

  9. svn转git合并代码

    在Git Bash 中输入 git-svn clone http://devsvnread.uuzuonline.net/GOT_PRIVATE/server/ --no-metadata -T tr ...

  10. 线段树模板(HDU 6356 Glad You Came)

    题目: HDU 6356 http://acm.hdu.edu.cn/showproblem.php?pid=6356 很裸的线段树 #include<bits/stdc++.h> #de ...