Spring Cloud Ribbon源码分析

Spring Cloud Alibaba-Ribbon的源码分析 我们在看源码的时候我们可以根据功能先想一下,他是怎样实现的,如果让我们来实现我们会怎么做,我们想ribbon不过就是替换nx-stock,为ip+端口我们会怎样做,大家想一下?是不是我们可以增加加一个拦截器, 如下,你这样有这样一个思维再去看源码就应该容易一点:我们RestTemplate有一个扩展点是ClientHttpRequestInterceptor 我们Ribbon通过LoadBalancerInterceptor实现了这个扩展早点,将nx-stock替换为 192.168.0.3:8003。 阅读详情

一、ILoadBalancer

Ribbon实现负载均衡的核心接口为ILoadBalancer

public interface ILoadBalancer {
   //添加后端服务
  public void addServers(List<Server> newServers);

  //选择一个后端服务
  public Server chooseServer(Object key); 

//标记一个服务不可用
  public void markServerDown(Server server);

//获取当前可用的服务列表
  public List<Server> getReachableServers();

//获取所有后端服务列表
   public List<Server> getAllServers();
}

ILoadBalancer 接口的类层结构如下所示:

 核心功能实现在BaseLoadBalancer类中,核心组件有IRule、IPing和LoadBalancerStats等。

1. IRule

IRule 接口是对负载均衡策略的一种抽象,可以通过实现这个接口来提供各种适用的负载均衡算法

public interface IRule{
    public Server choose(Object key);

    public void setLoadBalancer(ILoadBalancer lb);
    public ILoadBalancer getLoadBalancer();
}

choose 方法是该接口的核心方法,根据key从指定服务列表中获取对应的服务

2. IPing

IPing 接口判断目标服务是否存活,定义如下:

public interface IPing {
    public boolean isAlive(Server server);
}

        可以看到 IPing 接口中只有一个 isAlive() 方法,通过对服务发出"Ping"操作来获取服务响应,从而判断该服务是否可用。

3.  LoadBalancerStats    

        LoadBalancerStats 类记录负载均衡的实时运行信息,用来作为负载均衡策略的运行时输入。

       ILoadBalancer接口中的chooseServer方法是实现负载均衡的核心方法,BaseLoadBalancer定义的chooseServer方法实现如下:

public Server chooseServer(Object key) {
        if (counter == null) {
            counter = createCounter();
        }
        counter.increment();
        if (rule == null) {
            return null;
        } else {
            try {
                return rule.choose(key);
            } catch (Exception e) {
                 return null;
            }
        }
}

        这里使用了 IRule 接口的 choose 方法选择服务信息,负载均衡算法可以分成两大类,即静态负载均衡算法和动态负载均衡算法。静态负载均衡算法比较容易理解和实现,典型的包括随机(Random)、轮询(Round Robin)和加权轮询(Weighted Round Robin)算法等。典型动态算法包括源 IP 哈希算法、最少连接数算法、服务调用时延算法等。

二、负载均衡策略

        Ribbon实现的负载均衡策略如下图所示:

        

RandomRule:随机策略

RoundRobbinRule:轮询策略

RetryRule:请求失败的重试策略,属于容错机制

WeightedResponseTimeRule:该策略与请求的响应时间有关,显然,如果响应时间越长,就代表这个服务的响应能力越有限,那么分配给该服务的权重就应该越小。

BestAvailableRule :选择一个并发请求量最小的服务器,逐个考察服务器然后选择其中活跃请求数最小的服务器。

AvailabilityFilteringRule:通过检查 LoadBalancerStats 中记录的各个服务器的运行状态,过滤掉那些处于一直连接失败或处于高并发状态的后端服务器。

三、Spring Cloud Netflix Ribbon

         Spring Cloud Netflix Ribbon组件在Netflix Ribbon组件上进行封装和集成,调用关系如下:

  1. @LoadBalanced 注解

为什么通过 @LoadBalanced 注解创建的 RestTemplate 就能自动具备客户端负载均衡的能力?

在 Spring Cloud Netflix Ribbon 中存在一个自动配置类——LoadBalancerAutoConfiguration 类。

LoadBalancerAutoConfiguration类的核心功能如下:

  1. 创建一个LoadBalancerInterceptor的Bean,用于实现对客户端发起请求时进行拦截, 以实现客户端负载均衡
  2. 创建一个RestTemplateCustomizer的Bean,用于给RestTemplate增加拦截器
  3. 维护了一个被@LoadBalanced 注解修饰的RestTemplate对象列表, 并在这里进行初始化, 通过调用RestTemplateCustomizer的实例来给需要客户端负载均衡的RestTemplate增加LoadBalancerinterceptor拦截器。

在LoadBalancerAutoConfiguration 类中,维护着一个被 @LoadBalanced 修饰的 RestTemplate 对象的列表。在初始化的过程中,对于所有被 @LoadBalanced 注解修饰的 RestTemplate,调用 RestTemplateCustomizer 的 customize 方法进行定制化,该定制化的过程就是对目标 RestTemplate 增加拦截器 LoadBalancerInterceptor,如下所示:

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
static class LoadBalancerInterceptorConfig {

   @Bean
   public LoadBalancerInterceptor loadBalancerInterceptor(
         LoadBalancerClient loadBalancerClient,
         LoadBalancerRequestFactory requestFactory) {
      return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
   }

   @Bean
   @ConditionalOnMissingBean
   public RestTemplateCustomizer restTemplateCustomizer(
         final LoadBalancerInterceptor loadBalancerInterceptor) {
      return restTemplate -> {
         List<ClientHttpRequestInterceptor> list = new ArrayList<>(
               restTemplate.getInterceptors());
         list.add(loadBalancerInterceptor);
         restTemplate.setInterceptors(list);
      };
   }

}

         这个 LoadBalancerInterceptor 用于实时拦截,可以看到它的构造函数中传入了一个对象 LoadBalancerClient,而在它的拦截方法本质上就是使用 LoadBalanceClient 来执行真正的负载均衡。LoadBalancerInterceptor 类代码如下所示:

public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {

   private LoadBalancerClient loadBalancer;

   private LoadBalancerRequestFactory requestFactory;

   public LoadBalancerInterceptor(LoadBalancerClient loadBalancer,
         LoadBalancerRequestFactory requestFactory) {
      this.loadBalancer = loadBalancer;
      this.requestFactory = requestFactory;
   }

   public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
      // for backwards compatibility
      this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
   }

   @Override
   public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
         final ClientHttpRequestExecution execution) throws IOException {
      final URI originalUri = request.getURI();
      String serviceName = originalUri.getHost();
      Assert.state(serviceName != null,
            "Request URI does not contain a valid hostname: " + originalUri);
      return this.loadBalancer.execute(serviceName,
            this.requestFactory.createRequest(request, body, execution));
   }

}

        可以看到这里的拦截方法 intercept 直接调用了 LoadBalancerClient 的 execute 方法完成对请求的负载均衡执行

   2. LoadBalanceClient 接口

public interface LoadBalancerClient extends ServiceInstanceChooser {

   <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;

   <T> T execute(String serviceId, ServiceInstance serviceInstance,
         LoadBalancerRequest<T> request) throws IOException;
   URI reconstructURI(ServiceInstance instance, URI original);
}

        这里有两个 execute 重载方法,用于根据负载均衡器所确定的服务实例来执行服务调用。而 reconstructURI 方法则用于构建服务 URI,使用负载均衡所选择的 ServiceInstance 信息重新构造访问 URI,也就是用服务实例的 host 和 port 再加上服务的端点路径来构造一个真正可供访问的服务。

   LoadBalancerClient接口的实现类有RibbonLoadBalancerClient和BlockingLoadBalancerClient,在RibbonLoadBalancerClient类中choose方法

public ServiceInstance choose(String serviceId, Object hint) {
   Server server = getServer(getLoadBalancer(serviceId), hint);
   if (server == null) {
      return null;
   }
   return new RibbonServer(serviceId, server, isSecure(server, serviceId),
         serverIntrospector(serviceId).getMetadata(server));
}

choose方法最终调用getServer获取服务

protected Server getServer(ILoadBalancer loadBalancer, Object hint) {
   if (loadBalancer == null) {
      return null;
   }
  

   return loadBalancer.chooseServer(hint != null ? hint : "default");
}

        这里的 loadBalancer 对象就是前面介绍的 Netflix Ribbon 中的 ILoadBalancer 接口的实现类。这样,我们就把 Spring Cloud Netflix Ribbon 与 Netflix Ribbon 的整体协作流程串联起来。

Spring Cloud Ribbon源码分析(Spring Cloud Kubernetes) 在项目中使用Ribbon的目的是在客户端(服务消费端)实现负载均衡。 在上一篇《Spring Cloud OpenFeign源码分析》中我们分析了为什么使用OpenFeign时,不配置url,且不导入Ribbon的依赖会报错。本篇继续分析OpenFeign是如何与Ribbon整合、Ribbon是如何实现负载均衡的、Ribbon是如何从注册中心获取服务的。 OpenFeign与Ribbon整合后的接口调用流程 OpenFeign与Ribbon整合实现负载均衡调用接口的流程如下: spring-clo. 阅读详情

相关推荐

AI Agent Harness Engineering 监控与日志系统搭建

在生成式AI(Generative AI)与大语言模型(LLM)普及的今天,AI Agent(自主智能代理)已经成为了继「LLM API调用」「单轮/多轮对话」之后的第三代AI应用范式——Agent能够自主感知环境、制定多步决策、调用外部工具(Web搜索、数据库、RAG检索、企业系统API等)、执行复杂任务并优化自身策略。然而,随着Agent应用从Demo原型快速落地到企业生产环境,一系列与工程化落地强绑定的可观测性(Observability)问题正在成为Agent项目成功上线、稳定运行的最大瓶颈。

AI开发架构师 184

客户端负载均衡Ribbon之源码解析

文章首发于微信公众《程序员果果》 地址:https://mp.weixin.qq.com/s/seYEMxztE2ZqfmaI8pO-7w 什么是负载均衡器? 假设有一个分布式系统,该系统由在不同计算机上运行的许多服务组成。但是,当用户数量很大时,通常会为服务创建多个副本。每个副本都在另一台计算机上运行。此时,出现 “Load Balancer(负载均衡器)”。它有助于在服务器之间平均分配传入...

程序员果果的博客 318

鼎捷T100——二次开发:维护作业添加非实体字段

非实体字段添加

weixin_52342654的博客 1160

聊聊RibbonLoadBalancerClient的choose方法

序 本文主要研究一下RibbonLoadBalancerClient的choose方法 RibbonLoadBalancerClient.choose spring-cloud-netflix-ribbon-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java p...

weixin_33697898的博客 3357

手机Camera硬件电路设计:从电源管理到信号完整性的实战解析

本文深入解析了手机Camera硬件电路设计的核心挑战与实战经验,重点聚焦于电源管理与信号完整性两大基石。文章详细阐述了AVDD、DVDD、IOVDD和AFVDD四路电源的差异化设计要点与噪声控制策略,并剖析了MIPI等高速信号通道的完整性设计原则,为硬件工程师提供了从理论到PCB布局布线的完整实战指南。

weixin_28308325的博客 255

企查查爬取实战

实战成果完成接口定位、抓包参数拆解、签名逆向、报错修复全流程调试,梳理出企查查多层风控逻辑;最终按照搜索分页规则,规范整理出两页共 20 条结构化企业数据,以标准 JSON 格式本地保存,字段完整、数据排版规范。现存局限平台顶层设备指纹与人机验证风控,纯 requests 网络请求模式无法突破;高频请求还存在账号限流、IP 访问限制风险,爬虫稳定性受平台策略影响较大。技术收获。

czr2026的博客 1133

【源码品读】负载均衡策略解析-1

@Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } protected int chooseRandomInt(int serverCount) { return ThreadLocalRandom.current().nextInt(serverCount); } /** * Randomly choose from all living servers */ @ed.

Leon_Jinhai_Sun的博客 236

武汉理工大学数据结构综合实验——连连看游戏综合实践

文章目录实验目的主要仪器设备及耗材一、实验要求二、分析与设计(非线性结构)1.数据结构的设计2.核心算法设计一条直线消子两条直线消子三条直线消子初始化游戏地图搜寻路径提示和重排3.测试用例设计4.测试效果总结 实验目的 (1)线性结构实验目的 调研连连看游戏,了解连连看游戏的功能和规则等 掌握集成开发工具VS2019的使用和C++的基础编程 了解MFC框架 了解线性结构,掌握数组的遍历、消子和胜负判断等算法 了解企业软件开发过程,应用迭代开发思路进行项目开发,养成良好的编程习惯和培养软件工程化思维 .

mo_zhe的博客 7613

第三节:Ribbon负载均衡Rule详解

1、负载均衡流程 1.orde-service发起请求经过Ribbon 2.Ribbon到eureka-server中拉取服务列表 3.Ribbon负载均衡选择服务 4.然后修改请求url,将服务名替换为真正的url地址发起请求。 2、Ribbon负载均衡实现 public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor { @Override public ClientHttpResponse interce

1555

嵌入式存储入门:Emmc控制器与设备工作原理全解析(附Synopsys/Arasan架构图)

本文深入解析了嵌入式系统中Emmc控制器与设备的工作原理,重点剖析了其作为CPU与存储设备桥梁的核心架构。通过对比Synopsys和Arasan两家主流IP厂商的控制器设计,详细阐述了DMA引擎与FIFO缓冲模块如何协同工作以提升数据传输效率,并提供了从硬件PCB布局到驱动调试的实战指南,帮助硬件工程师与开发者优化系统性能。

weixin_29248653的博客 149

使用mid360运行lio-livox对比fast-lio2

msg_type为激光雷达发出的数据格式,有livox自定义数据类型格式CustomMsg和ros标准的PointCloud2格式,因此首先需要确定激光雷达端配置的是哪种格式。可以从激光雷达的ros驱动中看到驱动端有三种格式可以选,驱动端的数字2对应lio-livox中的1,驱动端的0对应lio-livox的格式0。如果使用的是Ubuntu18.04编译完成后运行直接成功,如果使用20.04运行会报错,需要修改以下源代码。针对livox-mid360 运行lio-livox的一些问题。

z1872385的博客 1231

负载均衡策略_Spring cloud Ribbon 客户端负载均衡详解(三)负载均衡策略

通过之前的源码解读,我们已经对Ribbon实现的负载均衡器以及其中包含的服务实例过滤器、服务实例信息的存储对象、区域的信息快照等都有了深入的认识和理解,但是对于负载均衡器中的服务实例选择策略只是讲解了几个默认实现的内容,而对于IRule的其他实现还没有详细的解读,下面我们来看看在Ribbon中共提供了那些负载均衡的策略实现。如上图所示,我们可以看到在Ribbon中实现了非常多的选择策略,其中也包含...

weixin_39596739的博客 396

[QMT和ptrade量化交易小白入门]-121、如何用K-means聚类,每月自动筛选高流动性ETF

本专栏主要是介绍QMT和ptrade的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写200篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 829

spring cloud ribbon源码分析总结

Spring Cloud Ribbon笔记总结01 Spring Cloud Ribbon只是一个工具类框架,虽然不需要独立部署,但是几乎存在于每一个Spring Cloud构建的微服务和基础设施中。而且,ribbon实现的是客户端的负载均衡。 客户端负载均衡 负载均衡是对系统的高可用,网络压力的环节和处理能力扩容的重要手段之一。分为硬件负载均衡和软件负载均衡。 硬件负载均衡:通过服务器...

lingboo111的博客 352

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

spring cloud ribbon负载均衡源码分析及看源码的方法

文章目录spring cloud ribbonribbon自动装配LoadBalanced的作用ribbonInterceptor执行拦截器负载算法获取服务异步执行请求总结 spring cloud ribbon 众所周知springcloud ribbon 是用来做负载均衡的。那么它是怎么做到使restTemplate拥有负载均衡呢?带着这个疑问咱们来源码分析。 本文会详细介绍阅读源码的方式。如果从多实现中找到具体实现。(非idea断点方式) ribbon自动装配 demo 配置文件 server:

warape的博客 375

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Spring Cloud——Ribbon以及源码分析

一.RestTemplate简介 RestTemplate是Spring Resources中一个访问第三方RestFul API接口的网络请求框架。RestTemplate的设计原则和其他的Srping Template类似。都是为执行复杂任务提供一个具有默认行为的简单方法。 RestTemplate是用来消费Rest服务的,所以RestTemplate的主要方法都与Rest的Http协议的一些方法紧密相连。例如HEAD,GET,POST,DELETE等方法。这些方法在RestTemplate类对应的

努力找工作呀 330

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Spring Cloud源码分析之Ribbon

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

IT_Luobin的博客 288

Spring Cloud学习 之 Spring Cloud Ribbon(执行流程源码分析)

Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 文章目录分析:总结: 分析: ​ 在上篇文章中,我们着重分析了RestTemplate,主要是因为,如果我们采用Ribbon进行服务间的调用的话,要用到这个类,现在我们就先来看看怎么使用RestTemplate配合Ribbon进行服务间的调用。 @SpringBootApplicat...

做一个认真的程序员 1483

【九】Spring Cloud Ribbon源码分析

一、简介及核心原理 Ribbo有两种结合使用的方式,一种是与RestTemplate结合使用,另外一种是与Feign结合使用,下面是结合RestTemplate的配置。 @SpringBootApplication @EnableEurekaClient @EnableFeignClients @EnableHystrix public class OrderApp { public static void main(String[] args) { SpringAppl.

Sid小杰的博客 842

spring cloud Ribbon运用与源码分析

spring cloud Ribbon运用与源码分析简介项目搭建搭建ribbon端pom文件引入的相关依赖application.properties的配置关于code的编写Controller层的编写service层的编写config的编写LoadBalanceClient 简介与演示源码分析 简介 关于负载均衡,大部分互联网从业者都有了解,本文就简单描述一下,不进行深挖。常见的负载均衡有两种,...

434

Spring Cloud源码分析(二)Ribbon

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

小飞侠的博客 3925

Spring Cloud Kubernetes Ribbon源码分析

在项目中使用Ribbon的目的是在客户端(服务消费端)实现负载均衡。 在上一篇《Spring Cloud OpenFeign源码分析》中我们分析了为什么使用OpenFeign时,不配置url,且不导入Ribbon的依赖会报错。本篇继续分析OpenFeign是如何与Ribbon整合、Ribbon是如何实现负载均衡的、Ribbon是如何从注册中心获取服务的。 OpenFeign与Ribbon整合后的接口调用流程 OpenFeign与Ribbon整合实现负载均衡调用接口的流程如下: spr...

qingdao666666的博客 628

Ribbon与Spring cloud整合源码分析

简价 Ribbon是一种客户端的负载均衡器。提供了多种负载均衡的算法,支持多种协议(HTTP,TCP,UDP),并提供了故障容错的能力。官方网址为:https://github.com/Netflix/ribbon。 Ribbon版Hello World 我们再使用的时候需要指定Server对象也就是可以做为负载的服务器,以及负载的Rule规则,默认采用的...

everyok的博客 395
上一篇: Spring Cloud Ribbon使用
下一篇: 理解服务容错
思维的深度
博客等级 码龄11年 2万+粉丝 391原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值