Ribbon负载均衡原理

news2024/11/26 22:28:09

一、先看下流程图

在这里插入图片描述
备注:红色后面都为拦截器的逻辑,主要是加载配置文件【LoadBalancerAutoConfiguration】,对发送http请求的RestTemplate进行包装拦截,逻辑拦在拦截器里面。

二、LoadBalancerAutoConfiguration

负载均衡用到配置类:LoadBalancerAutoConfiguration

LoadBalancerAutoConfiguration主要做2个事情。

1、生成Bean: LoadBalancerInterceptor  拦截器
2、生成Bean: RestTemplateCustomizer   这个是RestTemplate的包装对象,里面拿到上面生成的拦截器,
然后把拦截器添加到RestTemplate里面去。restTemplate每次执行方法请求时,都会调用【intercept方法】执行拦截,
在intercept方法里面,通过【服务名】获取了该服务对应的【负载均衡器ILoadBalancer】的实例对象,
然后调用该实例的chooseServer方法获取一个具体【服务实例】,然后发送http请求服务提供者。

三、LoadBalancerClient

Ribbon中有个非常重要的组件LoadBalancerClient,它是【负载均衡的客户端】,通过LoadBalancerClient的方法,
我们只需要传一个【服务名】,那么LoadBalancerClient就会根据【服务名】返回对应的【负载均衡器】

而LoadBalancerClient是一个接口,真正的实现类正是RibbonLoadBalancerClient,逻辑都在choos方法里面,
先通过【服务Id】拿到ILoadBalancer,这个也叫【负载均衡器】

下面看下ILoadBalancer【负载均衡器】:ILoadBalancer的实现类有ZoneAwareLoadBalancer,
主要包含以下2个内容
1、里面的allServerList列表已经缓存了所有的服务列表,
2、里面还有个属性IRule,这个就是真正负载均衡算法的核心

当负载均衡器调用chooseServer方法时,会通过负载均衡算法IRule,返回哪一个具体的Server,这个就是我们最终要调用的服务Ip+端口。


ILoadBalancer接口定义了Ribbon中核心的两项内容,【服务获取】与【服务选择】,
可以说ILoadBalancerRibbon中最重要的一个组件,它起到了承上启下的作用,既要连接 Eureka获取服务地址,
又要调用IRule利用负载均衡算法选择服务

服务获取

Ribbon在选择之前需要获取服务列表,而Ribbon本身不具有服务发现的功能,
所以需要借助Eureka来解决获取服务列表的问题, 其实在获取实例的过程中,
1、先他得到一个EurekaClient的实例,然后借助EurekaClient的服务发现功能,来获取服务的实例列表。
2、在获取了实例信息后,判断服务的状态如果为UP,那么最终将它加入serverList中。

在获取得到serverList后,会进行缓存操作。首先进入BaseLoadBalancer的setServerList方法,
里面会往下面2个缓存赛数据,将拉取的serverList赋值给缓存列表allServerList。 

protected volatile List<Server> allServerList = Collections.synchronizedList(new ArrayList<Server>());
protected volatile List<Server> upServerList = Collections.synchronizedList(new ArrayList<Server>());



RibbonEureka中得到了服务列表,缓存在本地List后,存在一个问题,如何保证在调用服务的时候服务仍然处于可用状态,
也就是说应该如何解决缓存列表脏读问题?


在默认负载均衡器ZoneAwareLoadBalancer#setupPingTask方法中,里面创建了一个定时任务,使用ping的方式判断服务是否可用。

怎么ping的呢,不是判断网络通不通,这个ping只是他的方法这么叫,实际上还是通过查询EurekaServer返回服务的状态来判断。
因为本地的serverList为缓存值,可能与eureka中不同,所以从eureka中去查询该实例的状态,
如果eureka里面显示该实例状态为UP,就返回true,说明服务可用。
通过调用EurekaServer的接口,获取到服务的状态列表后,进行循环,如果状态改变,加入到changedServers中,
并且把所有可用服务加入newUpList,最终更新upServerList中缓存值

除了使用ping的方式去检测服务是否在线外,Ribbon还使用了别的方式来更新服务列表。使用了定时调度线程池调用了PollingServerListUpdater#start方法,来进行更新服务操作


Ribbon为了解决服务列表的脏读现象,采用了两种手段:
1、更新列表  (定时任务)
2、ping机制 (定时任务)

更新机制和ping机制功能基本重合,并且在ping的时候不能执行更新,在更新的时候不能运行ping,所以很难检测到ping失败的情况。

负载均衡算法

在这里插入图片描述

Ribbon默认使用的是ZoneAvoidanceRule,也叫【区域亲和】负载均衡算法,优先调用一个zone区间中的服务,
并使用轮询算法。

当然,也可以由我们自己实现IRule接口,重写其中的choose方法来实现自己的负载均衡算法,然后通过@Bean的方式注入到spring容器中。
当然也可以将不同的服务应用不同的IRule策略,这里需要注意的是,Spring cloud的官方文档中提醒我们,
如果多个微服务要调用不同的IRule,那么创建出IRule的配置类不能放在ComponentScan的目录下面,
这样所有的微服务都会使用这一个策略。

总结

综上所述,在Ribbon的负载均衡中,大致可以分为以下几步:
1、拦截请求,通过请求中的url地址,截取服务名称
2、通过LoadBalancerClient获取ILoadBalancer
3、使用Eureka获取服务列表
4、通过IRule负载均衡策略选择具体服务
5ILoadBalancer通过IPing及定时更新机制来维护服务列表
6、重构该url地址,最终调用HttpURLConnection发起请求

了解了整个调用流程后,我们更容易明白为什么Ribbon叫做客户端的负载均衡。与nginx服务端负载均衡不同,
1、nginx在使用反向代理具体服务的时候,调用端不知道都有哪些服务。
2Ribbon在调用之前,已经知道有哪些服务可用,直接通过本地负载均衡策略调用即可。
而在实际使用过程中,也可以根据需要,结合两种方式真正实现高可用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1167074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring集成高性能队列Disruptor

Disruptor简介 Disruptor&#xff08;中文翻译为“破坏者”或“颠覆者”&#xff09;是一种高性能、低延迟的并发编程框架&#xff0c;最初由LMAX Exchange开发。它的主要目标是解决在金融交易系统等需要高吞吐量和低延迟的应用中的并发问题。 Disruptor特点 无锁并发&#x…

kibana中文设置

安装目录下&#xff1a; 修改config/kibana.yml文件&#xff0c;添加如下配置 i18n.locale: "zh-CN"如图&#xff1a; 保存后&#xff0c;重启kibana即可

分组select获取每组用户最新时间的那条数据的查询方式

分组select获取每组用户最新时间的那条数据的查询方式,使用子查询内连接的方式实现 selecttp.user_id AS userId,tp.operator,DATE_FORMAT(tp.create_time,%Y-%m-%d %H:%i:%s) AS operateTimefrom 表名 t1 INNER JOIN(select user_id, max(create_time) max_time from 表名whe…

LeakCanary - Android的内存泄漏检测库

官网 GitHub - square/leakcanary: A memory leak detection library for Android. LeakCanary 项目简介 LeakCanary’s knowledge of the internals of the Android Framework gives it a unique ability to narrow down the cause of each leak, helping developers drama…

知识付费系统小程序开发中的最新趋势和技术是什么?

在迅速发展的移动应用市场中&#xff0c;知识付费系统小程序成为了在线学习和知识传递的重要形式。随着技术的不断进步&#xff0c;了解最新的趋势和技术对于开发知识付费系统小程序至关重要。本文将讨论当前在这一领域中备受关注的最新趋势和技术。 1. 跨平台开发框架的崛起…

赢在电商设计!2024年最新电商设计实战技巧盘点

双十一、双十二、黑五的电商大促即将轮番将至&#xff0c;电商运营人迎来大忙季&#xff0c;选品、直播、采购入库、售后……各种环节都是影响电商转化的关键因素&#xff0c;而电商设计作为打通这些环节&#xff0c;打造高转化率电商平台的关键要素&#xff0c;能够吸引用户注…

淘宝(PC端和APP端)商品详情API接口,可批量采集,高并发请求

淘宝&#xff08;PC端和APP端&#xff09;商品详情API接口&#xff0c;可批量采集&#xff0c;高并发请求代码如下&#xff1a; 淘宝商品详情API接口可以获取到商品的详细信息&#xff0c;以下是一个示例&#xff1a; 请求方式&#xff1a;使用HTTP或HTTPS协议&#xff0c;向指…

android studio安卓模拟器启动了但是看不到画面解决办法

当你使用android studio开发软件的时候&#xff0c;可能会遇到这个问题&#xff0c;就是当你点击下拉框中的启动模拟器的时候&#xff0c;看着程序是启动了&#xff0c;并且运行了&#xff0c;但是看不到模拟器界面&#xff0c;如下图&#xff1a; 这个时候&#xff0c;就要停止…

老年性聋不仅是听不到那么简单,如何避免让它来的更晚一些?

你是否有过这样的经历&#xff0c;和老年人聊天时&#xff0c;他们总是让你重复说话&#xff0c;或者说“你说话太小声了&#xff0c;我听不清楚”&#xff1f;这可能是老年性聋的一个信号。 据统计&#xff0c;老年性聋是全球老年人口中第二大常见疾病&#xff0c;也是全球第三…

【React】【react-globe.gl】3D Objects效果

目录 想要实现的效果实现过程踩坑安装依赖引入页面 想要实现的效果 示例地址 实现过程 踩坑 示例是通过script引入的依赖&#xff0c;但本人需要在react项目中实现该效果。按照react-globe.gl官方方法引入总是报错 Cant import the named export AmbientLight from non EcmaS…

pb:导入EXCEL,提示“不能连接EXCEL”

pb:导入EXCEL,提示“不能连接EXCEL” ------------------------------------------------------------------------------------------------------------------------------- 1.pb连上EXCEL代码: //从EXCEL读取文件 STRING LS_PATH,LS_FILE,ls_file_tmp oleobject ole_1…

三国志14信息查询小程序(历史武将信息一览)制作更新过程02-基本架构

0&#xff0c;前期准备 &#xff08;1&#xff09;一台有公网IP的云服务器&#xff0c;服务器上安装MySQL数据库&#xff0c;启用IIS服务。出入端口号配置运行&#xff08;服务器和平台都要配置&#xff09;&#xff0c;IIS服务器上安装SSL证书 &#xff08;2&#xff09;域名…

Astah Professional 全功能专业UML建模工具软件

Astah Professional是Mac上一款全新的轻量级UML建模工具。软件集思维导图和UML建模于一体&#xff0c;采用100%纯JAVA构建&#xff0c; 兼容性强&#xff0c;不仅能够实现分布式建模、项目合并&#xff0c;还能够实现和其它建模工具的交互。 Astah Professional软件优点 1、易…

Maven修改仓库和镜像地址

目录 1、修改仓库地址2、修改镜像地址 1、修改仓库地址 使用IDEA时,如果不指定自己下载的Maven,idea会默认使用自带的Maven 3&#xff08;bundle)。maven 3默认的仓库路径一般是在c盘的用户文件夹中的.m2目录下&#xff1a; 当maven下的pom文件中的依赖逐渐增加时,maven仓库下…

leetcode:26. 删除有序数组中的重复项(python3解法)

难度&#xff1a;简单 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数…

Android 13 GTS GtsPermissionControllerHostTestCases Test Failed

Android13 平板项目测试GtsPermissionControllerHostTestCases Failed&#xff0c;失败日志如下&#xff1a; java.lang.AssertionError: on-device tests failed: com.android.gts.permissioncontroller.PermissionControllerTest29#testGranted: java.lang.NullPointerExcep…

搭建专属品牌的独立题库小程序,自定义小程序名称和Logo|题库刷题小程序定制开发

土著刷题Plus专业版&#xff0c;以【录题-分组-刷题-考试】为中心打造一套完备的在线组卷刷题学习平台&#xff0c;自定义品牌名称和Logo&#xff0c;入驻后&#xff0c;您将拥有自己独立的企业级专业运营管理平台。 土著刷题Plus专业版v1.3.1版本&#xff0c;我们迭代了独立小…

uniapp踩坑之项目:uniapp数字键盘组件—APP端

//在components文件夹创建digitKeyboard文件夹&#xff0c;再创建digitKeyboard.vue <!-- 数字键盘 --> <template><view class"digit-keyboard"><view class"digit-keyboard_bg" tap"hide"></view><view clas…

【Spring Boot】发送邮件功能

发送邮件功能 一.pom.xml文件添加邮件依赖二.发送邮件信息&#xff08;1&#xff09;固定配置在application.yml&#xff08;2&#xff09;发送邮箱配成活&#xff08;3&#xff09;底层发送邮件方法&#xff08;4&#xff09;QQ邮箱开通smtp服务&#xff08;5&#xff09;网易…

基础课17——智能客服系统

客户服务是一种以客户为中心的服务模式&#xff0c;旨在提高客户满意度和忠诚度&#xff0c;促进企业业务增长和可持续发展。在客户服务中&#xff0c;企业需要了解客户需求&#xff0c;提供优质、高效、个性化的服务&#xff0c;解决客户问题&#xff0c;满足客户需求&#xf…