Ribbon负载均衡原理

一、先看下流程图

在这里插入图片描述
备注:红色后面都为拦截器的逻辑,主要是加载配置文件【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.mzph.cn/news/128798.shtml

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

相关文章

数据结构 - ArrayList - 动态修改的数组

目录 实现一个通用的顺序表 总结 包装类 装箱 / 装包 和 拆箱 / 拆包 ArrayList 与 顺序表 ArrayList基础功能演示 add 和 addAll &#xff0c;添加元素功能 ArrayList的扩容机制 来看一下&#xff0c;下面的代码是否存在缺陷 模拟实现 ArrayList add 功能 add ind…

什么是 DevOps

DevOps是一套融合软件开发&#xff08;Dev&#xff09;和 IT 运营&#xff08;Ops&#xff09;的实践&#xff0c;旨在缩短应用程序开发周期并确保以高软件质量持续交付&#xff0c;通过采用 DevOps 实践&#xff0c;您可以帮助组织更可靠、更快速、更高效地交付软件。 什么是…

SLAM从入门到精通(计算点到直线的距离)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 大家一开始看到这个题目的时候&#xff0c;也许比较吃惊。为什么会有这样的题目&#xff1f;但是做过slam的同学&#xff0c;应该就比较熟悉和了解…

Echats-自定义图表1

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"zh-cmn-Hans"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>…

uniapp生命周期

uniapp生命周期包括应用生命周期、页面生命周期和组件生命周期&#xff1b; 1、应用生命周期 app.vue/uvue是uni-app的朱组件。所有页面都是在app.vue下进行切换&#xff0c;是应用入口文件。但app.vue本身不是页面&#xff0c;这里补鞥编写视图元素&#xff0c;也就没有。 这…

vue生命周期

1、vue声明周期及生命周期函数 vue声明周期 每一个vue实例从创建到销毁的过程&#xff0c;就是这个vue实例的生命周期。在这个过程中&#xff0c;他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程&#xff1b; 生命周期&#xff1a;…

唇形驱动媲美头部厂商,青否数字人SaaS系统6.0重磅发布!

青否数字人SaaS系统6.0重磅发布&#xff01;唇形驱动效果及清晰度媲美硅基等头部厂商&#xff0c;同时优化数字人短视频模块。 唇形驱动媲美头部 青否数字人SaaS系统6.0版本重点优化了唇形驱动&#xff0c;AI技术已经实现与真人形象的1:1克隆&#xff0c;唇形、牙齿和舌头高清…

当科技遇上神器:用Streamlit定制AI可视化问答界面

Streamlit是一个开源的Python库&#xff0c;利用Streamlit可以快速构建机器学习应用的用户界面。 本文主要探讨如何使用Streamlit构建大模型外部知识检索的AI问答可视化界面。 我们先构建了外部知识检索接口&#xff0c;然后让大模型根据检索返回的结果作为上下文来回答问题。…

【AUTOSAR】【以太网】DoIp

AUTOSAR专栏——总目录_嵌入式知行合一的博客-CSDN博客文章浏览阅读217次。本文主要汇总该专栏文章,以方便各位读者阅读。https://xianfan.blog.csdn.net/article/details/132072415 目录 一、概述 二、功能描述 2.1 Do

DNS 域名解析协议

作用 将域名转化位IP地址 域名 用’ . ’ 隔开的字符串&#xff0c;如&#xff1a;www.badu.com,就是为了赋予IP特殊含义。 一级域名 .com &#xff1a;公用 .cn&#xff1a;中国 .gov&#xff1a;政府 .us&#xff1a;美国 .org&#xff1a;组织 .net&#xff1a;网站 对应一级…

HTML脚本、字符实体、URL

HTML脚本&#xff1a; JavaScript 使 HTML 页面具有更强的动态和交互性。 <script> 标签用于定义客户端脚本&#xff0c;比如 JavaScript。<script> 元素既可包含脚本语句&#xff0c;也可通过 src 属性指向外部脚本文件。 JavaScript 最常用于图片操作、表单验…

Vue路由导航(replace、push、forward、back、go)

Vue路由导航&#xff08;replace、push、forward、back、go&#xff09; 先了解栈结构&#xff0c;再学习以下内容 栈的数据结构&#xff1a;先进后出&#xff0c;后进先出。原理&#xff1a;push将元素压入栈内&#xff0c;pop将元素弹出&#xff0c;栈有分别有栈底指针和栈顶…

C++11 initializer_list 轻量级初始化列表的使用场景(让自定义类可以用初始化列表的形式来实例化对象)

initializer_list 是 C11 中的一个特性&#xff0c;它允许你使用花括号 {} 中的值列表来初始化容器或数组。通常用于初始化标准库容器&#xff0c;比如 std::vector、std::set、std::map 以及数组。 场景一&#xff1a;用初始化列表初始化容器 std::vector<int> arr {…

Java中Deque栈对象的增删查(所有方法详解)

1、Deque栈的增删查方法总结 2、方法增删查 栈顶添加&#xff1a;push、offFirst栈尾添加&#xff1a;add、offer、offerLast栈顶删除&#xff1a;remove、pop、poll、pollFirst栈尾删除&#xff1a;pollLast栈顶查看&#xff1a;peek、peekFirst栈尾查看&#xff1a;peekLast…

搭载基于RK3229的Android5.1修改开机默认桌面Launcher

1、找到ActivityManagerService.java 在..\rk3229_5.1_box\frameworks\base\services\core\java\com\android\server\am目录找到ActivityManagerService.java文件。在文件里找到startHomeActivityLocked函数里的setDefaultLauncher。 boolean startHomeActivityLocked(int use…

软件设计模式原则(一)迪米特法则

开一个小专题——详细总结一下软件设计模式原则&#xff0c;这部分在《软计》和《java设计模式》中算是很重要的知识点&#xff0c;值得展开详细讲解一下~首先介绍的是【迪米特法则】 一.定义 迪米特法则又称为最少知识原则&#xff0c;其定义为&#xff1a;一个软件实体应当尽…

微众银行备用金怎么取出来

在这个数字时代里&#xff0c;互联网金融产品以其便捷性和创新性逐渐成为我们日常生活中不可或缺的一部分。微众银行作为国内领先的互联网银行&#xff0c;其旗下的微众备用金产品凭借其灵活、便捷的特性&#xff0c;深受消费者喜爱。那么&#xff0c;微众备用金怎么借钱出来呢…

JavaScript中BOM与DOM

BOM window对象 所有的浏览器都支持window对象&#xff0c;他表示浏览器窗口&#xff0c; 所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。 全局变量是 window 对象的属性。全局函数是 window 对象的方法。 接下来要讲的HTML DOM 的 document 也是…

【设计模式】第24节:行为型模式之“模板方法模式”

一、简介 模板方法模式在一个方法中定义一个算法骨架&#xff0c;并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下&#xff0c;重新定义算法中的某些步骤。 模板模式有两大作用&#xff1a;复用和扩展。其中&#xff0c;复用指的是&#…

Tailwind CSS vs 现代CSS,Tailwind CSS 会像CSS-in-JS 一样亡?

本文是 关于Tailwind CSS 与 现代 CSS之间比较的文章。文章中作者详细比较了这两种CSS开发方法的优缺点。他指出&#xff0c;Tailwind CSS是一种基于类的CSS框架&#xff0c;提供了快速开发网站的便利性&#xff0c;但可能导致HTML代码的臃肿。另一方面&#xff0c;现代CSS方法…