当前位置:网站首页>【云原生】原来2020.0.X版本开始的OpenFeign底层不再使用Ribbon了
【云原生】原来2020.0.X版本开始的OpenFeign底层不再使用Ribbon了
2022-07-31 05:11:00 【m0_67392811】
文章目录
一、前言
在前面的Feign系列文章:
- SpringCloud之Feign实现声明式客户端负载均衡详细案例
- SpringCloud之OpenFeign实现服务间请求头数据传递(OpenFeign拦截器RequestInterceptor的使用)
- SpringCloud之OpenFeign的常用配置(超时、数据压缩、日志)
- SpringCloud之OpenFeign的核心组件(Encoder、Decoder、Contract)
- SpringBoot启动流程中开启OpenFeign的入口(ImportBeanDefinitionRegistrar详解)
- 源码剖析OpenFeign如何扫描所有的FeignClient
- 源码剖析OpenFeign如何为FeignClient生成动态代理类
- 图文源码剖析OpenFeign处理请求流程
我们聊了以下内容:
- OpenFeign的概述、为什么会使用Feign代替Ribbon
- Feign和OpenFeign的区别
- 详细的OpenFeign实现声明式客户端负载均衡案例
- OpenFeign中拦截器RequestInterceptor的使用
- OpenFeign的一些常用配置(超时、数据压缩、日志输出)
- SpringCloud之OpenFeign的核心组件(Encoder、Decoder、Contract)
- 在SpringBoot启动流程中开启OpenFeign的入口
- OpenFeign如何扫描 / 注册所有的FeignClient
- OpenFeign如何为FeignClient生成动态代理类
- OpenFeign处理请求流程
本文基于OpenFeign高版本(SpringCloud 2020.0.x版本开始之后的版本)讨论:OpenFeign新版本和旧版本之间的差异(高版本OpenFeign底层不使用Ribbon做负载均衡)
PS:本文使用的SpringCloud高版本:
<properties>
<spring-boot.version>2.4.2</spring-boot.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--整合spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--整合spring cloud alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
PS:本文使用的SpringCloud低版本:
<properties>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
</properties>
二、源码主流程版本间差异串讲
1、@FeignClientsRegistrar开启对FeignClient的扫描
此处主流程上无区别;
在SpringBoot启动流程中@FeignClientsRegistrar注解开启OpenFeign的入口、OpenFeign扫描所有的FeignClient的流程 高版本和低版本基本一样,低版本的见文章:[这里是代码005]注解开启OpenFeign的入口、OpenFeign扫描所有的FeignClient。
主要流程如下:
1> 开启扫描FeignClient的入口:
- 启动类上添加的
@EnableFeignClients注解会通过@Import注解在SpringBoot启动流程中将ImportBeanDefinitionRegistrar接口的实现类FeignClientsRegistrar注入到启动类的ConfigurationClass的属性中,在注册启动类的BeanDefinition时,会遍历调用其@Import的所有ImportBeanDefinitionRegistrar接口的 registerBeanDefinitions()方法。2> 扫描FeignClient:
- 拿到@EnableFeignClients注解中配置的扫描包路径相关的属性,得到要扫描的包路径;
- 获取到扫描器
ClassPathScanningCandidateComponentProvider,然后给其添加一个注解过滤器(AnnotationTypeFilter),只过滤出包含@FeignClient注解的BeanDefinition;- 扫描器的findCandidateComponents(basePackage)方法从包路径下扫描出所有标注了@FeignClient注解并符合条件装配的接口;然后将其在BeanDefinitionRegistry中注册一下;
2、为FeignClient生成动态代理类
区别主要体现在这里;
在注册FeignClient到Spring容器时,构建的BeanDefinition的beanClas是FeignClientFactoryBean;FeignClientFactoryBean是一个工厂,保存了@FeignClient注解的所有属性值,在Spring容器初始化的过程中,其会根据之前扫描出的FeignClient信息构建FeignClient的动态代理类。
具体的动态代理类生成流程参考博文:OpenFeign如何为FeignClient生成动态代理类;
底层通信Client的区别?
在使用Feign.Builder构建FeignClient的时候,获取到的Client是FeignBlockingLoadBalancerClient(这其中的逻辑后面聊,在OpenFeign低版本是LoadBalancerFeignClient);用于生成FeignClient的Targeter是DefaultTargeter(在OpenFeign低版本是HystrixTargeter,高版本移除了Hystrix,采用Spring Cloud Circuit Breaker 做限流熔断);
具体体现在FeignClientFactoryBean#loadBalance()方法,其是一个进行负载均衡的FeignClient动态代理生成方法;
OpenFeign低版本:
1> FeignBlockingLoadBalancerClient何时注入到Spring容器?
FeignBlockingLoadBalancerClient注入到Spring容器的方式和OpenFeign低版本的LoadBalancerFeignClient是一样的;
进入到FeignBlockingLoadBalancerClient类中,看哪里调用了它唯一一个构造函数;

找到FeignBlockingLoadBalancerClient发现有三个地方调用了它的构造函数,new了一个实例;
- DefaultFeignLoadBalancedConfiguration
- HttpClientFeignLoadBalancedConfiguration
- OkHttpFeignLoadBalancedConfiguration
再结合默认的配置,只有DefaultFeignLoadBalancedConfiguration中的Client符合条件装配;

可以通过引入Apache HttpClient的maven依赖使用HttpClientFeignLoadBalancedConfiguration,
或引入OkHttpClient的maven依赖并在application.yml文件中指定feign.okhttp.enabled属性为true使用OkHttpFeignLoadBalancedConfiguration。
2> DefaultTargeter在哪里注入到Spring容器?
DefaultTargeter注入到Spring容器的方式和OpenFeign低版本的HystrixTargeter是一样的;
在FeignAutoConfiguration类中可以找到Targeter注入到Spring容器的逻辑;

3> 后续生成动态代理类的逻辑和旧版本一样
都体现在ReflectiveFeign#newInstance()方法中:

3、**Client处理负载均衡(核心区别)
上面提到OpenFeign高版本获取到的Client是FeignBlockingLoadBalancerClient,而低版本的是LoadBalancerFeignClient,LoadBalancerFeignClient基于Ribbon实现负载均衡,FeignBlockingLoadBalancerClient就靠OpenFeign自己实现负载均衡;
OpenFeign如何处理一个HTTP请求见博文:图文源码剖析OpenFeign处理请求流程。
接下来浅看一下FeignBlockingLoadBalancerClient是如何做负载均衡的!!
1)FeignBlockingLoadBalancerClient选择一个服务实例

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
猜你喜欢

Object Detection Study Notes

12 【网页布局总结 元素的显示与隐藏】

The interviewer asked me how to divide the database and the table?Fortunately, I summed up a set of eight-part essays

继承、Super,重写、抽象类、抽象方法 1(第七天)

Three-party login using wallet Metamask based on web3.0

12 【nextTick 过渡与动画】
uni-app进阶之样式框架/生产环境【day10】

leetcode-每日一题1252. 奇数值单元格的数目(模拟优化)

实验8 DNS解析

Access数据库的查询
随机推荐
12 【网页布局总结 元素的显示与隐藏】
联盟链的真实场景在哪里
tf.keras.utils.pad_sequences()
数据库上机实验3 连接查询和分组查询
10 【高度塌陷与BFC】
正则表达式基础知识
win11中利用IIS10搭建asp网站
C语言文件读、写、定位函数
【Elastic-Job】分布式调度任务概览篇
uni-app进阶之模版语法与数据绑定【day7】
PHP中abstract(抽象)、final(最终)和static(静态)原理与用法
Swordsman Offer Special Assault Edition ---- Day 6
利用phpstudy搭建DVWA
剑指offer专项突击版 ---第 5 天
剑指offer专项突击版 --- 第 3 天
12 【nextTick 过渡与动画】
leetcode-每日一题735. 行星碰撞(栈模拟)
数据库上机实验6 数据库完整性
leetcode-1833. 雪糕的最大数量(排序+贪心)
Swordsman Offer Special Assault Edition --- Day 3