0


【云原生】原来2020.0.X版本开始的OpenFeign底层不再使用Ribbon了

文章目录

一、前言

在前面的Feign系列文章:

  1. SpringCloud之Feign实现声明式客户端负载均衡详细案例
  2. SpringCloud之OpenFeign实现服务间请求头数据传递(OpenFeign拦截器RequestInterceptor的使用)
  3. SpringCloud之OpenFeign的常用配置(超时、数据压缩、日志)
  4. SpringCloud之OpenFeign的核心组件(Encoder、Decoder、Contract)
  5. SpringBoot启动流程中开启OpenFeign的入口(ImportBeanDefinitionRegistrar详解)
  6. 源码剖析OpenFeign如何扫描所有的FeignClient
  7. 源码剖析OpenFeign如何为FeignClient生成动态代理类
  8. 图文源码剖析OpenFeign处理请求流程

我们聊了以下内容:

  1. OpenFeign的概述、为什么会使用Feign代替Ribbon?
  2. Feign和OpenFeign的区别?
  3. 详细的OpenFeign实现声明式客户端负载均衡案例
  4. OpenFeign中拦截器RequestInterceptor的使用
  5. OpenFeign的一些常用配置(超时、数据压缩、日志输出)
  6. SpringCloud之OpenFeign的核心组件(Encoder、Decoder、Contract)
  7. 在SpringBoot启动流程中开启OpenFeign的入口
  8. OpenFeign如何扫描 / 注册所有的FeignClient
  9. OpenFeign如何为FeignClient生成动态代理类
  10. 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的流程 高版本和低版本基本一样,低版本的见文章:FeignClientsRegistrar注解开启OpenFeign的入口、OpenFeign扫描所有的FeignClient。

主要流程如下:

1> 开启扫描FeignClient的入口:

  1. 启动类上添加的@EnableFeignClients注解会通过@Import注解在SpringBoot启动流程中将ImportBeanDefinitionRegistrar接口的实现类FeignClientsRegistrar注入到启动类的ConfigurationClass的属性中,在注册启动类的BeanDefinition时,会遍历调用其@Import的所有ImportBeanDefinitionRegistrar接口的 registerBeanDefinitions()方法。

2> 扫描FeignClient:

  1. 拿到@EnableFeignClients注解中配置的扫描包路径相关的属性,得到要扫描的包路径;
  2. 获取到扫描器ClassPathScanningCandidateComponentProvider,然后给其添加一个注解过滤器(AnnotationTypeFilter),只过滤出包含@FeignClient注解的BeanDefinition;
  3. 扫描器的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选择一个服务实例

在这里插入图片描述


本文转载自: https://blog.csdn.net/Saintmm/article/details/125947294
版权归原作者 秃秃爱健身 所有, 如有侵权,请联系我们删除。

“【云原生】原来2020.0.X版本开始的OpenFeign底层不再使用Ribbon了”的评论:

还没有评论