码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【云原生】原来2020.0.X版本开始的OpenFeign底层不再使用Ribbon了


    文章目录

    • 一、前言
    • 二、源码主流程版本间差异串讲
      • 1、@FeignClientsRegistrar开启对FeignClient的扫描
      • 2、为FeignClient生成动态代理类
        • 底层通信Client的区别?
          • 1> FeignBlockingLoadBalancerClient何时注入到Spring容器?
          • 2> DefaultTargeter在哪里注入到Spring容器?
          • 3> 后续生成动态代理类的逻辑和旧版本一样
      • 3、**Client处理负载均衡(核心区别)
        • 1)FeignBlockingLoadBalancerClient选择一个服务实例

    一、前言

    在前面的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高版本:

    
        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
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

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

    
        2.3.7.RELEASE
        Hoxton.SR9
        2.2.6.RELEASE
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    1、@FeignClientsRegistrar开启对FeignClient的扫描

    此处主流程上无区别;

    在SpringBoot启动流程中@FeignClientsRegistrar注解开启OpenFeign的入口、OpenFeign扫描所有的FeignClient的流程 高版本和低版本基本一样,低版本的见文章:[这里是代码005]注解开启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选择一个服务实例

    在这里插入图片描述

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

  • 相关阅读:
    CentOS7搭建keepalived+DRBD+NFS高可用共享存储
    基于SpringBoot的健身房管理系统
    volatile 类型变量提供什么保证?能使得一个非原子操作变成原子操作吗?
    华为---静态路由-浮动静态路由及负载均衡(二)
    借助cpolar 和大家分享有趣的照片 1 (在本地电脑上部署piwigo网页)
    try catch finally注意事项
    MySql 实现递归with recursive
    vue使用本地图片设置为默认图
    ABAP datum_range中的四个组件的作用
    [面试直通版]操作系统之锁、同步与通信(下)
  • 原文地址:https://blog.csdn.net/m0_67392811/article/details/126080740
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号