• 再谈微服务负载均衡器:Ribbon均衡器和SpringCloud自带LoadBalancer均衡器


    1 缘起

    Spring稳步向前发展,功能迭代,Bug修复,
    对于应用工程师而言,不同版本的Spring对于开发还是有不小的影响,
    比如,服务熔断、负载均衡,
    SpringCloud2020.0.3版本:
    (1)使用新的熔断组件:Resilience4j替代Hystrix,
    (2)使用自带的负载均衡LoadBalancer替代Ribbon,
    不同项目中使用不同的SpringCloud版本,应用时,各自处理各自的,有很强的割裂感,
    打算先从负载均衡器开始,对比分析一下Ribbon和LoadBalancer负载均衡器,
    包括两者默认的负载均衡策略、如何找到默认的负载均衡规则、如何自定义负载均衡规则,
    帮助读者理解和记忆,轻松应知识考核场景。

    2 负载均衡

    简单理解:雨露均沾,如下图所示。我认为理想情况下的“均”不是平均,而是合适,
    合理利用机器资源,让每台机器的利用率都在合适的范围。
    在不同的业务场景下,催生了不同的负载均衡策略,如随机、轮询、最小连接数策略等,
    共同的目的是保证服务可用,合理利用集群中的机器资源。
    在这里插入图片描述
    Spring中常用的负载均衡器有:Ribbon和LoadBalancer,
    本文也是针对这两种负载均衡器展开分析的。

    版本说明:
    Ribbon:2.3.0
    LoadBalancer:3.0.3

    3 Ribbon负载均衡器

    Netflix出品。

    3.1 负载均衡策略

    这里仅列出负载均衡策略,不细讲,后续会另写文章分析。

    序号均衡策略描述
    1AvailabilityFilteringRule可用过滤规则,先过滤出故障或并发请求大于阈值的服务实例,然后线性轮询其余的实例
    2BestAvailableRule最优可用规则,过滤故障后的服务实例,选择并发量最小的实例
    3RandomRule随机规则,随机选择
    4RetryRule重试规则,从服务实例轮询获取服务,失败,则重新轮询实例
    5RoundRobinRule轮询规则,从服务列表中顺序获取服务
    6WeightedResponseTimeRule响应时间加权轮询
    7ZoneAvoidanceRule最佳区域实例集合中选择性能最优的服务

    3.2 默认负载均衡策略

    AvailabilityFilteringRule,可用过滤规则。先过滤出故障或并发请求大于阈值的服务实例,
    然后线性轮询剩余的实例,分配请求。

    3.2.1 入口类

    老规矩,找到入口,Ribbon构造负载均衡器入口源码如下图所示。
    位置:com.netflix.loadbalancer.LoadBalancerBuilder
    由源码可知,并没有注释,见名知意,这就是构建负载均衡器的入口类,有默认配置config,自定义配置rule等属性。
    在这里插入图片描述

    3.2.2 构建负载均衡策略方法

    构建负载均衡器的具体实现(入口)方法源码如下图所示,
    位置:com.netflix.loadbalancer.LoadBalancerBuilder#buildFixedServerListLoadBalancer
    由源码可知,并且为了分析方便,特将构建负载均衡器可分为4个步骤,如下图的标号,
    (1)构建负载均衡器;
    (2)创建负载均衡规则;
    (3)创建Rule;
    (4)获取默认规则;
    在这里插入图片描述

    3.2.2.1 第二步:创建负载均衡规则

    通过这个配置,可以获取负载均衡默认属性,如负载均衡器、负载均衡规则等,
    config的值,源码如下图所示,
    位置:com.netflix.client.config.DefaultClientConfigImpl#getClientConfigWithDefaultValues()
    有源码可知,配置的默认属性为getClientConfigWithDefaultValues()。
    在这里插入图片描述

    进入这个方法:getClientConfigWithDefaultValues(),
    看到默认的负载均衡器DEFAULT_PROPERTY_NAME_SPACE,
    源码如下图所示,由源码可知,使用的默认均衡器为ribbon,通过DefaultClientConfigImpl配置默认属性。
    在这里插入图片描述
    (1)默认的负载均衡器:ribbon

    位置:com.netflix.client.config.DefaultClientConfigImpl#DEFAULT_PROPERTY_NAME_SPACE
    在这里插入图片描述
    (2)默认属性配置实现
    位置:com.netflix.client.config.DefaultClientConfigImpl#DefaultClientConfigImpl(java.lang.String)
    com.netflix.client.config.DefaultClientConfigImpl#loadDefaultValues
    通过loadDefaultValues配置默认属性,如下图所示,默认的负载均衡规则Rule,在第三步讲。
    在这里插入图片描述
    DefaultClientConfigImpl中的属性properties用于存储默认属性值,如下图所示,具体的set和get感兴趣的可以继续看下源码,
    这里仅给出部分过程和结果。
    在这里插入图片描述

    3.2.2.2 第三步:创建规则Rule

    上面分析了填充默认属性值,接下来就可以获取配置以加载负载均衡器,
    通过get获取对应的规则类名称,源码如下图所示,
    由源码知,默认的Rule的键为:IClientConfigKey.Keys.NFLoadBalancerRuleClassName,
    位置:com.netflix.loadbalancer.LoadBalancerBuilder#createRuleFromConfig
    这个键对应的值是什么呢?
    在这里插入图片描述
    找到配置属性的地方,源码如下图所示,
    由源码知,默认的规则类名称通过getDefaultNfloadbalancerRuleClassname()获取。
    位置:com.netflix.client.config.DefaultClientConfigImpl#loadDefaultValues
    在这里插入图片描述
    默认规则类名称源码如下图所示,
    由源码知,默认的负载均衡规则为:
    位置:com.netflix.client.config.DefaultClientConfigImpl#getDefaultNfloadbalancerRuleClassname
    在这里插入图片描述
    在这里插入图片描述

    3.3 自定义负载均衡策略

    通过上面分析可知Ribbon默认会使用AvailabilityFilteringRule负载均衡策略,
    虽然比较繁琐,但是,自定义配置负载均衡策略就比较方便了,
    直接构造IRule类型的Bean即可,自定义构造负载均衡策略测试样例如下:

    package com.company.microserviceuser.config;
    
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RoundRobinRule;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * 负载均衡策略配置.
     *
     * @author xindaqi
     * @since 2022-09-01 18:17
     */
    @Configuration
    public class LoadBalancerConfig {
    
        /**
         * 轮询策略.
         *
         * @return 轮询对象
         */
        @Bean
        public IRule loadBalancerRule() {
            return new RoundRobinRule();
        }
    }
    
    • 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

    4 Loadbalancer负载均衡器

    Spring出品。

    4.1 负载均衡策略

    序号均衡策略描述
    1RandomRule随机规则,随机选择
    2RoundRobinRule轮询规则,从服务列表中顺序获取服务

    4.2 默认负载均衡策略

    RoundRobinLoadBalancer,轮询策略。
    默认的配置源码如下图所示,
    由源码可知,默认的负载均衡策略为RoundRobinLoadBalancer。
    位置:org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration
    在这里插入图片描述

    4.3 自定义负载均衡

    自定义负载均衡策略参照官方源码,
    因为,当前版本的负载均衡器只有两种均衡策略,
    所以,自定义的策略为随机均衡策略,
    配置样例如下:

    package com.monkey.tutorial.common.config;
    
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
    import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
    import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
    import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.env.Environment;
    
    /**
     * 负载均衡策略配置.
     *
     * @author xindaqi
     * @since 2022-09-01 18:13
     */
    @Configuration
    public class LoadBalancerConfig {
    
        /**
         * 随机负载均衡策略.
         *
         * @param environment               环境配置
         * @param loadBalancerClientFactory 负载均衡客户端工厂
         * @return 随机负载均衡对象
         */
        @Bean
        public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
                                                                                       LoadBalancerClientFactory loadBalancerClientFactory) {
            String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
            return new RandomLoadBalancer(
                    loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
        }
    }
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    5 小结

    (1)负载均衡器:Ribbon和LoadBalancer,其中,Ribbon是Netflix开发,LoadBalancer是Spring官方的项目;
    (2)Ribbon均衡器有7中均衡策略,LoadBalancer(3.0.3)有2中均衡策略;
    (3)Ribbon默认均衡策略为:可用过滤规则;LoadBalancer默认策略为轮询。

  • 相关阅读:
    linux遇到-bash-4.2$
    Android入门第10天-Android访问远程Spring Boot提供的Restful API接口
    大数据分析仓库Kylin
    python+flask计算机毕业设计web的智慧云医疗的设计与实现(程序+开题+论文)
    多线程环境下事务与锁的问题
    QML 碰到的奇怪问题
    Meta Llama 3 RMSNorm(Root Mean Square Layer Normalization)
    VNC:Timed out waiting for a response from the computer
    [Angular 基础] - routing 路由(下)
    Go 单元测试
  • 原文地址:https://blog.csdn.net/Xin_101/article/details/126648064