SpringCloud实践系列:Ribbon负载均衡

SpringCloud系列:负载均衡组件-Ribbon 前面几篇文章介绍了微服务相关的内容,比如什么是微服务,常见的一些服务注册中心组件,以及微服务之间是如何进行服务通信的。在微服务架构中还有常见的一种场景就是服务的负载均衡。今天就一起学习SpringCloud提供的负载均衡组件-Ribbon。Spring Cloud Ribbon是一个基于http和tcp的客户端负载均衡工具,是基于netflix ribbon实现的,通过Spring Cloud封装, 可以让我们将面向服务的resttemplate请求自动转换成客户端负载均衡的服务调用。 阅读详情

一、概述

1.1、什么是Ribbon

Ribbon是负载均衡器,用于解决服务集群的负载均衡

1.2、常见负载均衡

  • 集中式LB 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;

  • 进程内LB 将LB逻辑到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。

  • Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

1.3、Ribbon工作流程

二、快速使用

  • 导入依赖

    springcloud alibaba对Ribbon做了兼容,无需单独引用

     

```
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.0.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>Hoxton.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

```
  • 启动类加注解

    // 启动类上开启服务注册与发现功能
    @EnableDiscoveryClient 
    
    
  • 配置文件

    可以不写,直接使用默认的

    ribbon: 
        eager-load: 
            enabled: true # 是否立即加载(项目启动是,是否拉取实例列表),默认是false(项目启动不拉取,第一次请求时拉取).
            clients: # 指定哪些服务需要立即加载,数组形式
                - cloud-goods
                - cloud-goods2
    
    
  • 使用

    在RestTemplate配置文件中,加@LoadBalanced注解

    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.client.ClientHttpRequestFactory;
    import org.springframework.http.client.SimpleClientHttpRequestFactory;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class ApiConfig {
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
            return new RestTemplate(factory);
        }
    
        @Bean
        public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            factory.setReadTimeout(5000);
            factory.setConnectTimeout(5000);
            return factory;
        }
    }
    
    

三、源码简单追踪

3.1、源码简单追踪

在LoadBalancerAutoConfiguration类中有个ribbonInterceptor方法,该方法调了LoadBalancerInterceptor类

public class LoadBalancerAutoConfiguration {
    ......
    static class LoadBalancerInterceptorConfig {
        ......
        @Bean
        public LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) {
            return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
        }
        ......
    }    
}

LoadBalancerInterceptor类中有个关键的方法intercept,调用RibbonLoadBalancerClient的execute方法,获取实例列表

public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
    ......

    public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
        // 获得url
        URI originalUri = request.getURI();
        // 拿到serviceName
        String serviceName = originalUri.getHost();
        Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
        // 获取实例列表,实现负载均衡
        return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
    }
}

RibbonLoadBalancerClient类的execute方法中,获取实例列表,实现负载均衡

public class RibbonLoadBalancerClient implements LoadBalancerClient {
    public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {
        // 获取实例列表(先从本地缓存取,没有则从注册中心取)
        ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
        // 实现负载均衡(选取负载均衡策略)
        Server server = this.getServer(loadBalancer, hint);
        if (server == null) {
            throw new IllegalStateException("No instances available for " + serviceId);
        } else {
            RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
            return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);
        }
    }
}

3.2、Ribbon核心组件

接口作用默认值
IClientConfig读取配置DefaultClientConfigImpl
IRule负载均衡规则,选择实例ZoneAvoidanceRule
IPing筛选掉ping不通的实例DummyPing
ServerList交给Ribbon的实例列表Ribbon:ConfigurationBasedServerList Spring Cloud Alibaba:NacosServerList
ServerListFilter过滤掉不符合条件的实例ZonePreferenceServerListFilter
ILoadBalanceRibbon的入口ZoneAwareLoadBalance
ServerListUpdater更新交给Ribbon的List的策略PollingServerListUpdater

四、负载均衡策略

4.1、内置的负载均衡策略

Ribbon核心组件IRule: 根据特定算法从服务列表中选取一个需要访问的服务

IRule是一个接口,有7个自带的实现类,可以实现不同的负载均衡算法规则

规则名称特点
AvailabilityFilteringRule过滤掉一直连接失败的被标记为circuit tripped的后端Server,并 过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate 来包含过滤server的逻辑,其实就是检查status里记录的各个server 的运行状态
BestAvailableRule选择一个最小的并发请求的server,逐个考察server, 如果Server被tripped了,则跳过
RandomRule随机选择一个Server
ResponseTimeWeightedRule已废弃,作用同WeightedResponseTimeRule
WeightedResponseTimeRule根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低
RetryRule对选定的负载均衡策略加上重试机制,在一个配置时间段内当 选择Server不成功,则一直尝试使用subRule的方式选择一个 可用的Server
RoundRobinRule轮询选择,轮询index,选择index对应位置的Server
ZoneAvoidanceRule(默认)默认的负载均衡策略,即复合判断Server所在区域的性能和Server的可用性 选择Server,在没有区域的环境下,类似于轮询(RandomRule)【优中选优,再轮询】

4.2、切换ribbon负载均衡策略

  • 编写配置

    在客户端配置

    注意:不能在启动类的同级/子集下配置

    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RoundRobinRule;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyRibbonRule {
        @Bean
        public IRule getRule() {
            return new RoundRobinRule();
        }
    }
    
    
  • 配置启动类

    // 启动类上加该注解即可
    @RibbonClient(name = "cloud-goods", configuration = {MyRibbonRule.class})
    
    

4.3、自定义策略(使用Nacos权重)

直接在页面上修改权重,是无效的。因为负载均衡中引入了ribbon,没有改ribbon配置,还是使用的ribbon的默认负载均衡策略。

使用nacos的权重,需要自定义负载均衡策略

  • 配置权重

    • 在页面上配置

*   在代码中配置

    ```
    spring:
      application:
        name: cloud-goods # 服务名
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848 # 指定nacos-server的地址
            username: nacos
            password: nacos
            weight: 10
    server:
      port: 9001
    
    ```
  • 自定义负载均衡策略

    拿到nacos的配置,进行自定义的负载均衡策略

    注意:不能在启动类的同级/子集下配置

    import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
    import com.alibaba.cloud.nacos.ribbon.NacosServer;
    import com.alibaba.nacos.api.exception.NacosException;
    import com.alibaba.nacos.api.naming.NamingService;
    import com.alibaba.nacos.api.naming.pojo.Instance;
    import com.netflix.client.config.IClientConfig;
    import com.netflix.loadbalancer.AbstractLoadBalancerRule;
    import com.netflix.loadbalancer.BaseLoadBalancer;
    import com.netflix.loadbalancer.Server;
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class NacosWeightedRule extends AbstractLoadBalancerRule {
        /**
         * NacosDiscoveryProperties内置了基于权重的负载均衡算法
         */
        @Autowired
        private NacosDiscoveryProperties nacosDiscoveryProperties;
    
        /**
         * 读取配置文件并初始化NacosWeightedRule
         * @param iClientConfig
         */
        @Override
        public void initWithNiwsConfig(IClientConfig iClientConfig) {
    
        }
    
        /**
         * 实现基于权重的负载均衡算法
         * @param o
         */
        @Override
        public Server choose(Object o) {
            try {
                BaseLoadBalancer loadBalancer = (BaseLoadBalancer)this.getLoadBalancer();
                //想要请求的微服务名称
                String name = loadBalancer.getName();
                //拿到服务发现新的相关的api
                NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
                //Nacos client自动通过基于权重的负载均衡算法,给我们选择一个实例
                Instance instance = namingService.selectOneHealthyInstance(name);
                return new NacosServer(instance);
            } catch (NacosException e) {
                return null;
            }
        }
    }
    
    
  • 引用自定义的负载均衡策略

    • 引用配置类

      import com.netflix.loadbalancer.IRule;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration
      public class MyRibbonRule {
          @Bean
          public IRule getRule() {
              return new NacosWeightedRule();
          }
      }
      
      
    • 启动类

      // 启动类上加该注解即可
      @RibbonClient(name = "cloud-goods", configuration = {MyRibbonRule.class
SpringCloud系列之客户端负载均衡Netflix Ribbon 负载均衡是一种基础的网络服务,它的核心原理是按照指定的负载均衡算法,将请求分配到后端服务集群上,从而为系统提供并行处理和高可用的能力。提到负载均衡,你可能想到nginx。对于负载均衡,一般分为服务端负载均衡和客户端负载均衡 Ribbon 是由 Netflix 发布的负载均衡器,它有助于控制 HTTP 和 TCP 的客户端的行为。Ribbon 属于客户端负载均衡。 阅读详情

相关推荐

Mplus实战:随机截距交叉滞后模型(RI-CLPM)在心理学纵向研究中的进阶应用

本文深入探讨了随机截距交叉滞后模型(RI-CLPM)在心理学纵向研究中的进阶应用,通过Mplus实战演示了模型设定、结果解读及进阶建模策略。RI-CLPM能有效区分个体间差异和个体内变化,适用于追踪青少年手机使用与抑郁症状等研究。文章还提供了样本量规划、模型比较和结果可视化等实用技巧,助力研究者避免常见陷阱。

weixin_29220405的博客 369

Spring Cloud Ribbon的使用详解

Ribbon是Netflix发布的开源项目,`Spring Cloud Ribbon`是基于`Netflix Ribbon`实现的一套客户端`负载均衡`的框架。

怪咖@的博客 6822

element的el-cascader组件动态加载,以及报错处理问题

Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. 报错处理

weixin_56527169的博客 1264

springcloud微服务(十二)-ribbon基础知识

ribbon基础知识

weixin_51725434的博客 1097

保姆级教程:彻底清理Win11更新缓存并解除外设,一次搞定0xc1900101更新错误

本文提供了一套完整的Win11更新报错0xc1900101解决方案,涵盖软件环境净化和硬件设备隔离。通过终止干扰进程、重置更新组件、清理临时文件以及断开外设等步骤,有效提升更新成功率。特别强调外设驱动兼容性对解决0xc1900101错误的关键作用。

weixin_33483304的博客 417

【Pix4d精品教程】pix4d mapper相机未校准后手动添加连接点完美案例图文教程

如图所示,红色的照片为未校准的图片,软件无法自动获取连接点,有关相机未校准的原因及解决办法,可以参考《pix4d未校准相机:287 out of 402 images calibrated (71%), all images enabled, 6 block,问题分析及解决方案汇总》,本文以案例的形式,详细讲解pix4d中手动添加连接点的方法及操作步骤。 文章目录1. 手动添加连接点2. 重新优化3. 生成质量报告,检查精度 1. 手动添加连接点 在【空三射线】模式下查看校准失败的图片,记下照片的名称。.

智慧空间实验室 2万+

spring cloud中的ribbon的介绍和使用

spring cloud中的ribbon的介绍和使用

weixin_43731014的博客 551

阿里云百炼全解析:一站式大模型开发平台的架构与行业实践

摘要: 阿里云百炼平台通过一站式架构革新大模型开发范式,将传统碎片化工具链整合为统一工作流,实现开发周期从月级到小时级的跃迁。其核心架构包含接入层、引擎层与资源层,关键技术突破包括MCP服务协议、多模态引擎及高性能训练优化。平台提供全生命周期开发支持,从数据准备到模型部署,并通过VPC隔离、数据加密构建企业级安全体系。已在医疗、电力等行业实现显著增效,如阿斯利康药物分析系统准确率提升至95%。未来将向多Agent协同、边缘计算等方向演进,推动AI技术深度融入产业核心。

fudaihb的博客 1990

Ribbon负载均衡工作流程、策略修改及饥饿加载

Ribbon负载均衡工作流程、策略修改及饥饿加载

人生快意事,读的好书,觅得良友 666

华为OD机试2025C卷 - CPU调度策略 (C++ & Python & JAVA & JS & GO)

华为OD机试 2025C卷 CPU调度策略,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 1296

使用OpenGL加载和显示DXF格式的3D模型文件编程

这样,我们就完成了使用OpenGL加载和显示DXF格式的3D模型文件的编程。通过实现加载函数和绘制回调函数,我们能够读取DXF文件的数据并使用OpenGL绘制出来。请注意,这只是一个简单的例子,仅涵盖了基本的加载和显示功能。在本文中,我们将探讨如何使用OpenGL编程加载和显示DXF(Drawing Exchange Format)格式的3D模型文件。DXF是一种通用的CAD(计算机辅助设计)文件格式,常用于存储和交换2D和3D图形数据。使用OpenGL加载和显示DXF格式的3D模型文件编程。

2301_79331421的博客 413

Spring Cloud源码分析(二)Ribbon

在之前介绍使用Ribbon进行服务消费的时候,我们用到了RestTemplate,但是熟悉Spring的同学们是否产生过这样的疑问:RestTemplate不是Spring自己就有的吗?跟Ribbon的客户端负载均衡又有什么关系呢?下面在本文,我们来看RestTemplate和Ribbon是如何联系起来并实现客户端负载均衡的。 首先,回顾一下之前的消费者示例:我们是如何实现客户端负载均衡...

小飞侠的博客 408

代谢组数据分析(三十一):空间代谢组学分析从数据加载到通路分析的流程解析

空间代谢组学是一种先进的技术,能够在组织切片上以高分辨率检测代谢物分布,为理解生物代谢过程提供新视角。其分析流程包括数据获取、预处理、代谢物注释、差异表达分析、可视化、通路分析、聚类分析及空间相关代谢物分析等关键步骤。这些步骤帮助研究人员从海量数据中提取有价值信息,揭示代谢物的空间分布规律,发现潜在生物标志物,探索代谢通路调控机制。例如,SpaMTP等工具为全流程分析提供了强大支持,助力研究人员高效处理数据,深入理解代谢过程,为生物学研究和临床应用提供重要依据。

专注生信领域 918

【springcloud】springcloud 系列文章目录

springcloud 系列完结总结篇: springcloud 总体概述 《 springcloud 入门简介 》 服务注册与发现 《 eureka 服务注册与发现 概述篇 》 Eureka 的自我保护机制 《 Eureka 自我保护机制 》 Eureka 与 Zookeeper 对比 《 Eureka 与 Zookeeper 对比 》 Eureka 单机 与 集群搭建 《 Eurek...

梁兴龙的博客 648

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

SpringCloud系列教程目录

↓↓↓SpringCloud教程目录,点击直接进入文章↓↓↓,也可进入专栏: SpringCloud教程(Finchley版本)-00:什么是SpringCloud SpringCloud教程(Finchley版本)-01:服务注册与发现(Eureka) SpringCloud教程(Finchley版本)-02:服务消费者 SpringCloud教程(Finchley版本)-03:负载均衡(Rib...

IT云清 3314

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【SpringCloud】Ribbon负载均衡

在Eureka注册中心中我们在添加完@LoadBalanced注解,即可实现负载均衡功能,现在一起探索一下负载均衡的原理(Ribbon)。通过定义IRule实现可以修改负载均衡规则,有两种方式:@Beanuserservice: # 给某个微服务配置负载均衡规则,这里是userservice服务ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则以上就是关于Ribbon负载均衡的讲解。

浩泽学编程的博客 5999

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

SpringCloud-Ribbon负载均衡

Ribbon是一个客户端负载均衡器,类似于nginx的负载均衡模块功能,负载均衡(Load Balance)是用于解决一台机器无法解决所有请求而产生的一种算法,像nginx使用负载均衡分配流量,ribbon为客户端提供负载均衡,dubbo服务调用里的负载均衡、openfeign等很多地方使用到了负载均衡。 ......

知足上进,不负野心。 8984

SpringCloud-Ribbon实现负载均衡

本文从负载均衡的基本概念入手,探讨其在微服务体系中的重要性。详细介绍了在 SpringCloud 中使用 Ribbon 的步骤,包括引入依赖、添加注解和使用 RestTemplate 进行远程调用。通过本文的学习,读者将更好地理解和运用Ribbon,提升微服务架构的性能和可维护性。

踏雨歌青春,诗酒趁年华 2554

【SpringCloud】Ribbon 负载均衡

负载均衡原理和策略

bit me的博客 1575

SpringCloud Ribbon中的7种负载均衡策略

负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端负载均衡器,而我们今天的主角 Ribbon就属于后者——客户端负载均衡器。 服务端负载均衡器的问题是,它提供了更强的流量控制权,但无法满足不同的消费者希望使用不同负载均衡策略的需求,然而客户端负载均衡也有其缺点,如果配置不当,可能会导致服务提供者出现热点,或者压根就拿不到任何服务的情况,所以我们本文就来了解一下这 7 种内置负载均衡策略的具体规则。

小洁洁 3978

SpringCloud之负载均衡Ribbon

利用Ribbon实现负载均衡效果

weixin_46171048的博客 1581

【云原生】SpringCloud系列之客户端负载均衡Ribbon

在微服务架构中,负载均衡是必须使用的技术,通过它来实现系统的高可用、集群扩容等功能。负载均衡可以分为两种:服务端负载均衡和客户端负载均衡。通常所说的负载均衡指服务器负载均衡,可通过硬件设备或软件来实现,硬件比如:F5、Array等,软件比如:LVS、Nginx等。 负载均衡按实现方式分类可区分为:服务端负载均衡(比如Nacos负载均衡)与客户端负载均衡。 SpringCloud Ribbon是基于客户端的负载均衡工具,它可以将面向服务的 REST 模板请求自动转换成客户端负载均衡的服务调用。执行过程如下图:

write less , do more 7502

SpringCloud Ribbon 负载均衡服务调用

详细介绍下 Ribbon 负载均衡服务调用,以及手写负载均衡算法

快乐的小三菊的博客 1598

负载均衡Ribbon和Feign---SpringCloud

负载均衡Ribbon和Feign Ribbon负载均衡(基于客户端) 6.1 负载均衡以及Ribbon Ribbon是什么? Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端负载均衡的工具。 简单的说,Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。Ribbon 的客户端组件提供一系列完整的配置项,如:连接超时、重试等。简单的说,就是在配置文件中列出 LoadBalance

Frank---7的博客 14万+
上一篇: Sentinel源码-NodeSelectorSlot和ClusterBuilderSlot
下一篇: 京东T9架构师手把手教你怎么写年薪50万的java简历
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值