【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析

这篇具有很好参考价值的文章主要介绍了【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

微服务间相互调用的基础上,服务间的调用更多是以调用某多实例服务下的某个实例的形式。而这就需要用到负载均衡技术。对于开发者而言,只要通过@LoadBalance注解就开启了负载均衡。如此简单的操作底层究竟是什么样的,我想你也很想知道。

1.调用形式

在《SpringCloud集成Eureka并实现负载均衡》的基础之上,我们可以进行一个小小的实验,debug运行程序,通过postman发起一个请求,A服务会去远程调用B服务,debug发现发送的url为:http://user-service/user/1,毫无疑问的是,这就是A调用B的途径
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
同样地,拿到这个url我们去postman里发送请求:
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
发现请求无法发送出去,路径出了问题。观察路径中的参数user-service发现他是B服务的服务名称,那为什么在A服务里向B服务发送“服务名称-接口路径-参数”形式的请求就能够正常响应?
结合集成负载均衡的过程,这一定是Ribbon在发挥作用

2.LoadBalancerInterceptor

负载均衡的前提不是传递一个具体的url,肯定是Ribbon做了某种解析,通过服务名称得到了服务下的实例列表,从而拉取Eureka-Server中的服务注册表来将请求映射到指定的某个实例上。
结合曾经前后端分离的web开发经验,后端经常会在拦截器中拦截前端发来的请求来对请求做一些操作,比如校验、拼接、鉴权…调用方发送请求和接收方收到的请求并不一致,这其中会不会也是有一个类似于拦截器的东西拦截了请求,并且转换了请求呢?
答案是必然的,那是谁——LoadBalancerInterceptor
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
可以看到的是,他实现了ClientHttpRequestInterceptor接口,具体用法细节直接去看接口中声明的方法
直观的看出接口中声明了一个intercept()方法并且接受了HttpRequest参数来拦截了客户端的http请求,并且修改的请求体!这么一看URL更改的谜底就在此处揭晓了,那么方法底层具体是怎么实现的呢:

3.负载均衡流程分析

3.1 调用流程图

Debug源码之前先来看一下源码中的调用链路总体流程图(手图):
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
概括来看则是:拦截请求—读取服务—拉取服务列表—选择规则—返回服务实例

3.2 intercept()方法

下面我们开始Debug:
1.当发送请求使得服务间发生调用关系,调用请求会先传递到拦截器中的intercept方法,可以看到的是目前还和发送是保持一致
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
2.继续向下执行,开始解析请求,拿到了请求中的URI——通过getHost()方法拿到了主机地址(服务的名称)
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon

3.3 execute()方法

3.Ribbon开始做负载均衡处理
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
4.两次步入之后进入到execute()方法内部,发现传递进来的服务名称作为服务Id进入到了getLoadBalance()方法,并且得到了一个ILoadbalance接口对象,而在该对象中封装了很多的信息:
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
这里记住服务实例id的值:host.docker.internal:8084,这就是Eureka客户端接收到的实例信息

3.4 getServer()方法

5.接口对象作为参数传递到了getServer()方法,得到了一个server对象进入到方法内部。发现与此同时传递了一个Object类型的对象用于指定服务器的规则或条件,不过到目前为止,这个参数一直都是null作为传递,即loadBalancer.chooseServer()方法采用的是‘default’的方式进行选择
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon

3.4 子类的chooseServer()方法

6.再次步入到chooseServer()方法,发现是在一个名为BaseLoadBalancer类(这个类是负载均衡器的具体实现后面会具体分析)下重写的父类方法
此时:可以判断的是getLoadBalancerStats().getAvailableZones().size() <= 1为TRUE
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon

3.5 getLoadBalancerStats().getAvailableZones().size() <= 1

对于表达式:getLoadBalancerStats().getAvailableZones().size() <= 1进行分析
发现在BaseLoadBalancer类中通过继承抽象类AbstractLoadBalancer并重写getLoadBalancerStats()抽象方法,获取到了一个loadbalancer统计信息集合LoadBalancerStats
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
而封装在LoadBalancerStats中的信息里有一个ConcurrentHashMap类型的集合属性,即

volatile Map<String, List<? extends Server>> upServerListZoneMap = new ConcurrentHashMap<String, List<? extends Server>>();

用于存储可用的服务列表,这个集合中的每个条目都代表一个区域,键是区域名称,值是该区域下可用服务器的列表。
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
后续的.getAvailableZones()方法则是获取这一属性值中所有的键,也就是可用的服务区域,并作为Set集合返回来进行判断
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
很显然,这里进一步论证getLoadBalancerStats().getAvailableZones().size() <= 1是为true的,后续就会去调用父类的chooseServer()方法

3.6 父类的chooseServer()方法

7.步入到父类的chooseServer()方法中,发现最后返回了一个Server类型的对象,这肯定就是具体的服务实例信息了。
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon

3.7 IRule接口下的实例

去追踪rule变量,发现是一个IRule接口的实例,即为负载均衡提供规则的接口
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
并且此接口下有大量的规则实现,而默认的规则方式则为轮询调度
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
可是看到上图在debug时,rule变量右侧灰色显示的是rule:RandomRule@12045这是因为我通过配置IRule类型的Bean指定了负载均衡的规则:

    @Bean
    public IRule randomRule() {
        return new RandomRule();
    }

只要把他注释掉,程序就会继续去采用默认的规则即RoundRobinRule

3.8 最终的choose()方法—return server

8.了解了IRule接口的rule实例,再去看他最终调用的choose()方法。同样地步入进去,由于是默认规则,则按照流程进入到了RoundRobinRule规则实现中的choose方法(其实IRule接口下的每一个规则实现类都有choose方法)
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
实现了ILoadBalancer接口的负载均衡器对象作为参数传递到了方法中,与此同时key为default。开始为随机选择预热。

3.9 choose()方法内部分析

9.进入到while循环中,不断选择服务器,直到找到一个可用的服务器。随后会判断线程是否中断,如果中断了,则直接返回null。
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
这样的情况出现频率还是很高,由此可见,这个小设计会减少很多不必要计算,提升了程序运行的效率。
而后这是分别获取两个服务列表【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
从列表中选择一个
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
兜底操作,对选择的做判断【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
最后成功返回Server实例给chooseServer()方法,服务发起者发送http://user-service/user请求通过Ribbon最后轮询到了localhost:8084服务实例上

4. 彩蛋

现在有很多公司都在用Nacos替换Eureka,因为感知服务列表的变化不够敏感,感知下线服务太过迟钝,就像下面这种情况:
【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析,SpringCloud体系,Eureka,spring cloud,eureka,ribbon
服务实例已经下线,时间大约过了一分钟,却还是把下线的服务加载到了可用服务列表里(upList),其实这并不怪Ribbon,都是Eureka的错
针对这种情况我们留个彩蛋,下次再来talk about~文章来源地址https://www.toymoban.com/news/detail-751458.html

到了这里,关于【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springCloud之Eureka之负载均衡Ribbon

    说完了注册中心Eureka,虽然Eureka可以实现服务的发现和调用,但在微服务体系中,服务的发现和调用往往是需要伴随着负载均衡这个概念一体的。而在SpringCloud中自然也存在着与Eureka配套的负载均衡组件,也就是Ribbon组件。 Ribbon介绍 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套

    2024年02月05日
    浏览(32)
  • 38.SpringCloud—注册中心(eureka/nacos)、负载均衡Ribbon

    目录 一、SpringCloud。 (1)认识微服务。 (1.1)单体架构与分布式架构(微服务)。 (1.2)微服务技术对比。 (1.3)SpringCloud。 (2)服务拆分及远程调用。 (2.1)服务拆分。 (2.2)远程调用。 (3)提供者与消费者。 (4)Eureka注册中心。 (4.1)Eureka的作用。  (4.2)搭建

    2024年02月09日
    浏览(53)
  • 【SpringCloud】二、服务注册发现Eureka与负载均衡Ribbon

    服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务) 服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口) 很明显,这是一个相对的概念。 上一篇中,远程调用时,url参数是写死在代码中的,而不同的测试、生产、

    2024年02月06日
    浏览(46)
  • SpringCloud微服务 【实用篇】| Eureka注册中心、Ribbon负载均衡

    目录 一:Eureka注册中心 1. Eureka原理 2. 动手实践 ①搭建EurekaServer ②服务注册 ③服务发现  二:Ribbon负载均衡 1. 负载均衡原理 2. 负载均衡策略 3. 懒加载 tips:前些天突然发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家,感兴趣的同学可以

    2024年02月05日
    浏览(44)
  • springcloud Ribbon负载均衡服务调用

    地址:https://github.com/13thm/study_springcloud/tree/main/days6_Ribbon Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时

    2024年01月20日
    浏览(48)
  • SpringCloud实用篇1——eureka注册中心 Ribbon负载均衡原理 nacos注册中心

    单体架构: 将业务的所有功能集中在一个项目中开发,打成一个包部署。 优点:架构简单;部署成本低(打jar包、部署、负载均衡就完成了) 缺点:耦合度高(维护困难、升级困难,不利于大项目开发) 分布式架构 根据业务功能对系统做拆分,每个业务功能模块作为独立

    2024年02月13日
    浏览(33)
  • 1.3 eureka+ribbon,完成服务注册与调用,负载均衡源码追踪

    本篇继先前发布的1.2 eureka注册中心,完成服务注册的内容 。 目录 环境搭建 采用eureka+ribbon的方式,对多个user服务发送请求,并实现负载均衡 负载均衡原理 负载均衡源码追踪 负载均衡策略 如何选择负载均衡策略? 饥饿加载 复制(补充) 给order模块和user模块建立独立的数

    2024年02月14日
    浏览(44)
  • 详解SpringCloud微服务技术栈:强推!源码跟踪分析Ribbon负载均衡原理、Eureka服务部署

    👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:详解SpringCloud微服务技术栈:认识微服务、服务拆分与远程调用 📚订阅专栏:微服务技术全家桶 希望文章对你们有所帮助 服务提供者:一次业务中,被其它微服务调用的服务(提供接口给

    2024年01月18日
    浏览(43)
  • SpringCloud入门——微服务调用的方式 & RestTemplate的使用 & 使用nacos的服务名初步(Ribbon负载均衡)

    1.微服务调用的几种方式,异步消息传递,http调用,服务网关调用,服务发现调用nacos; 2.spring提供的restTemplate,发送HTTP请求的客户端工具类; 3.nacos使用服务名报错,需要加Ribbon负载均衡; RPC (Remote Procedure Call)远程过程调用协议,一种通过网络从远程计算机上请求服务,

    2024年02月10日
    浏览(39)
  • [日报] Ribbon、Eureka、Nginx、负载均衡

    目录 前言 一、Ribbon和Eureka的关系 二、Eureka知识笔记(个人理解) 三、关于Ribbon和Nginx的负载均衡区别 1、位置工作方式 2、策略 3、集中式与分布式 四、杂项 1、版本问题 2、一些课堂内容订正 3、Spring Cloud生态给出的替代方案 Spring Cloud LoadBalancer Spring Cloud Consul 完成度比较

    2024年03月18日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包