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

网友投稿 405 2022-08-23

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

文章目录

​​一、前言​​​​二、源码主流程版本间差异串讲​​

​​1、@FeignClientsRegistrar开启对FeignClient的扫描​​​​2、为FeignClient生成动态代理类​​

​​底层通信Client的区别?​​

​​1> FeignBlockingLoadBalancerClient何时注入到Spring容器?​​​​2> DefaultTargeter在哪里注入到Spring容器?​​​​3> 后续生成动态代理类的逻辑和旧版本一样​​

​​3、**Client处理负载均衡(核心区别)​​

​​1)FeignBlockingLoadBalancerClient选择一个服务实例​​

一、前言

在前面的Feign系列文章:

我们聊了以下内容:

本文基于OpenFeign高版本(​​SpringCloud 2020.0.x版本开始之后的版本​​)讨论:OpenFeign新版本和旧版本之间的差异(高版本OpenFeign底层不使用Ribbon做负载均衡)

PS:本文使用的SpringCloud高版本:

2.4.2 2020.0.1 2021.1 org.springframework.boot spring-boot-dependencies ${spring-boot.version} pom import org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import com.alibaba.cloud spring-cloud-alibaba-dependencies ${spring-cloud-alibaba.version} pom import

PS:本文使用的SpringCloud低版本:

2.3.7.RELEASE Hoxton.SR9 2.2.6.RELEASE

二、源码主流程版本间差异串讲

1、@FeignClientsRegistrar开启对FeignClient的扫描

此处主流程上无区别;

在SpringBoot启动流程中​​@FeignClientsRegistrar​​​注解开启OpenFeign的入口、OpenFeign扫描所有的FeignClient的流程 高版本和低版本基本一样,低版本的见文章:​​FeignClientsRegistrar注解开启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了一个实例;

DefaultFeignLoadBalancedConfigurationHttpClientFeignLoadBalancedConfigurationOkHttpFeignLoadBalancedConfiguration

再结合默认的配置,只有​​DefaultFeignLoadBalancedConfiguration​​中的Client符合条件装配;

可以通过引入Apache HttpClient的maven依赖使用HttpClientFeignLoadBalancedConfiguration,

或引入OkHttpClient的maven依赖并在application.yml文件中指定​​feign.okDefaultTargeter在哪里注入到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选择一个服务实例

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:把低俗当创意:“辣条一哥”卫龙为何戒不掉“黑红营销”!(卫龙辣条网络营销案例)
下一篇:【云原生&微服务十四】SpringCloud之深度源码剖析OpenFeign如何为FeignClient生成动态代理类
相关文章

 发表评论

暂时没有评论,来抢沙发吧~