百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

还没有秃头吗?你真的需要大牛来教你如何深入解析Ribbon源码了

toyiye 2024-08-25 15:54 8 浏览 0 评论

上文给大家讲解的内容是Ribbon的核心工作原理,那本章给大家讲解的内容是Ribbon源码解析。

Ribbon源码解析

Ribbon 的 源 码 解 析 我 们 从 @LoadBalanced 开 始 讲 起 , 添 加@LoadBalanced注解后AsyncRestTemplate就具备了负载均衡的能力,代码如下:

在初始化HTTP客户端时会加载Ribbon的拦截代码,同时根据配置文件中设置的负载均衡策略或者代码实现定制好的负载均衡策略,实现HTTP请求过程中的后端服务分发。所以源码解读可以分为两个部分。

● 初始化构造过程:获取@LoadBalanced注解标记RestTemplate或者AsyncRestTemplate,然后添加拦截器。

● 负载均衡服务选择过程:在Ribbon设定的负载均衡策略下,从服务集群中根据预定的负载均衡策略实现后端服务的选取及请求转发。

如下图所示是一个简要的Ribbon初始化及调用拦截HTTP请求实现负载均衡的流程。

Ribbon的初始化过程

@LoadBalanced注解对RestTemplate做了标记,使用Ribbon的自动化配置加载类实现对负载均衡客户端的加载,在生成的RestTemplate的Bean上添加注解后,它会配置LoadBalancerClient。首先我们看一下LoadBalancerClient的源码实现:

说明:LoadBalancerClient是一个接口,里面有三个方法。

● ServiceInstance choose(String serviceId)方法,根据传入的serviceId(服务名),从负载均衡器中选择一个服务实例,服务实例通过ServiceInstance类来表示。

● execute方法,使用从负载均衡器中选择的服务实例来执行请求内容。

● URI reconstructURI ( ServiceInstance instance , URIoriginal ) 方 法 : 用 来 重 新 构 建 URI 。 我 们 通 过RestTemplate 请 求 后 端 服 务 时 会 使 用 serviceId ( 服 务名),这个方法会把请求的URI进行转换,返回host+port,再通过host+port的形式去请求服务。

从META-INF/spring.factories文件来看Ribbon的自动化加载机制,主要是Spring Common的LoadBalancerClient的初始化和加载过程:

Ribbon的自动配置实现

下面是Ribbon的自动化配置实现:

● 说 明 1 # : Ribbon 将 所 有 标 记 @LoadBalanced 注 解 的RestTemplate保存到一个List集合中。

● 说 明 2 # : Ribbon 借 助 了 Spring IoC 容 器 的SmartInitializingSingleton机制。实现该接口后,当所有单 例 Bean 都 被 初 始 化 完 成 后 , 容 器 会 调 用afterSingletonsInstantiated实现RestTemplateCustomizer的customize定制化方法。

● 说 明 3 # : 获 取 RestTemplate 的 interceptors , 在 构 造LoadBalancerInterceptor时需要传入LoadBalanceClient实例参数,LoadBalanceClient是一个接口,具体实现类将实现choose(服务实例选择)和execute(请求转发执行)方法,这一步完成Ribbon负载均衡策略Bean的构造。

● 说明4:将说明3#中构造的loadBalancerInterceptor Bean实例注入RestTemplate的定制化Bean中,这一步骤也会在说明2# 的 afterSingletonsInstantiated 方 法 中 被 调 用 , 完 成RestTemplate的定制化及与LoadBalancerInterceptor实例关联。

Ribbon的重试策略

对于Ribbon的重试策略,可以参考RetryTemplate类的实现,它可以实现Ribbon的重试策略对RestTemplate的拦截控制,代码如下:

Ribbon的负载均衡行为逻辑

Ribbon主要在Spring Cloud Netflix中完成负载均衡行为的初始化过程,这部分初始化主要依赖spring-cloud-netflix-core模块。

下面我们看一下Ribbon在Spring Cloud中是如何实现初始化的,首先看Ribbon的自动加载机制META-INF/spring.factories:

下面是RibbonAutoConfiguration的实现,从源码中可以看到它会构 造 SpringClientFactory , LoadBalancerClient 初 始 化 构 造 需 要SpringClientFactory作为参数。

在Ribbon的自动化配置类中会通过RibbonClientConfiguration配置类获取YAML配置中的负载均衡配置,构造SpringClientFactory并生成LoadBalancer,代码如下:

可以看到,在RestTemplate执行HTTP请求时是如何通过Ribbon设置 的 拦 截 机 制 构 造 HTTP 客 户 端 请 求 的 。 RestTemplate 继 承 了InterceptingHttpAccessor,而父类InterceptingHttpAccessor提供了获取及添加拦截器的方法,代码如下:

InterceptingHttpAccessor抽象类的作用正是为我们添加自定义的拦截器:

这段代码的实际拦截器的实例注入(依赖注入)过程其实来自上面的Ribbon自动化配置类LoadBalancerAutoConfiguration,在配置类中它已经完成了拦截器的注册。

下面我们看一下当拦截HTTP请求后,RestTemplate将会执行哪些操作。首先,RestTemplate执行HTTP请求,从RestTemplate的实现源码 中 , 不 难 发 现 请 求 最 终 都 会 执 行 到 doExecute 方 法 中 。 查 看doExecute 的 调 用 链 路 , 我 们 发 现 它 都 会 执 行 到LoadBalancerInterceptor的intercept拦截方法中,代码如下:

我们跟进到Ribbon的执行 拦 截 逻 辑,LoadBalancerClient.execute方法的具体代码如下:

从 上 述 代 码 可 知 , Ribbon 首 先 根 据 服 务 的 serviceId 调 用getLoadBalancer方法得到ILoadBalancer。创建loadBalancer的过程可以理解为组装选取服务的规则、服务集群的列表、检验服务是否存活等特性的过程(加载RibbonClientConfiguration配置类)。这里的核 心 是 getServer 方 法 , 根 据 ILoadBalancer 来 选 取 一 个 具 体 的Server,选取的过程会按照服务的负载均衡策略、服务列表、服务存活 情 况 进 行 筛 选 判 断 , 对 我 们 自 定 义 的 负 载 均 衡 策 略 将 执 行chooseServer操作,最终根据这些约束选择一个后端的服务实例。

本文给大家讲解的内容是Ribbon源码解析

  1. 下篇文章给大家讲解的内容是微服务容错与隔离:隔离机制
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码