feign原理

  1. Feign远程调用,核心就是通过一系列的封装和处理,将以JAVA注解的方式定义的远程调用API接口,最终转换成为HTTP的请求形式,然后将HTTP的请求的响应结果,解码成JAVA Bean,放回给调用者。

  2. 流程

    1. @FeignClient远程调用接口
    2. JDK Proxy 动态代理实例
      1. 实现了远程调用接口,通过InvokeHandler调用处理器分发远程调用
    3. InvokeHandler
      1. 根据远程API的Method方法实例,进行MethodHandler方法处理器的分发
    4. MethodHandler
    5. ReuqestTemplate
      1. 根据实参,构造Request实例
    6. Encoder
      1. Reuqest请求的编码
    7. Interceptors,Logger
      1. 负责对请求和返回进行拦截处理,日志记录
    8. feign.Client
      1. 基于负载均衡,重试器,以及不同的HTTP请求框架,发送HTTP请求
    9. http request
    10. 远程server
    11. http response
    12. feign.Client
    13. Decoder
      1. response的解码
    14. Interceptors,Logger
    15. MethodHandler
    16. InvokeHandler
    17. JDK Proxy动态代理实例
    18. Resonse Bean
  3. 即Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数在应用到请求上,进而转化成真正的Request请求,通过Feign以及JAVA的动态代理机制,使得Java开发人员,可以不通过HTTP框架去封装HTTP请求报文的方式,完成远程服务的HTTP调用

  4. 在微服务启动时,Feign会进行包扫描,对加@FeignClient注解的接口,按照注解的规则,创建远程接口的本地JDK Proxy代理实例,然后将这些本地Proxy代理实例,注入到Spring IOC容器中,当远程接口的方法调用,由Proxy代理实例去完成真正的远程访问,并且返回结果

  5. 远程接口的本地JDK Proxy代理实例,有以下特点:

    1. Proxy代理实例,实现了一个加@FeignClient注解的远程调用接口
    2. Proxy代理实例,能在内部进行HTTP请求的封装,以及发送HTTP请求
    3. Proxy代理实例,能处理远程HTTP请求的响应,并且完成结果的解码,然后返回给调用者
  6. 使用:

    1. 加上@FeignClient注解,也就是说,Feign在启动时,会为其创建一个本地JDK Proxy代理实例,并注册到Spring IOC容器
    2. 通过@Resource注解,按照类型匹配,从Spring IOC容器找到这个代理实例,并且装配给需要的成员变量
    3. 为了创建Feign的远程接口的代理实现类,Feign提供了自己的一个默认的调用处理器,叫做FeignInvocationHandler类,该类处于feign-core核心包中,当然,调用处理器可以进行替换,如果Feign与Hystrix结合使用,则会替换成HystrixInvocationHandler调用处理器类,类处于feign-hystrix的jar包中。
  7. FeignInvocationHandler是一个相对简单的类,有一个非常重要的Map类型成员dispatch映射(private final Map<Method, MethodHandler> dispatch;),保存着远程接口方法到MethodHandler方法处理器的映射

  8. 默认的FeignInvocationHandler,在处理远程方法调用的时候,会根据Java反射的方法实例,在dispatch映射对象中,找到对应的MethodHandler方法处理器,然后交给MethodHandler,完成实际的HTTP请求和结果的处理,远程调用接口中有几个方法,其代理实现类的调用处理器FeignInvocationHandler的dispatch成员,就有几个key-value键值对

  9. invoke方法

    1. 首先,根据方法实例,从方法实例对象和方法处理器的映射中,取得方法处理器,然后调用方法处理器的invoke方法
    2. dispatch.get(method).invoke(args)
    3. 根据java反射的方法实例,在dispatch映射对象中,找到对应的MethodHandler方法处理器
    4. 调用MethodHandler方法处理器的invoke()方法,完成实际的Http请求和结果的处理
    5. MethodHandler方法处理器,和JDK动态代理机制中位于java.lang.reflect包的InvocationHandler调用处理器接口,没有任何继承和实现关系,MethodHandler仅仅是Feign自定义的,一个非常简单的接口
  10. 方法处理器MethodHandler

    1. Feign的方法处理器MethodHandler是一个独立的接口,定义在InvocationHandlerFactory接口中,仅仅拥有一个invoke()方法

    2. MethodHandler的invoke()方法,主要职责是完成实际远程URL请求,然后返回解码后的远程URL的响应结果,Feign提供了默认的SynchronousMethodHandler实现类,提供了基本的远程URL的同步请求处理,

    3. final class SynchronousMethodHandler implements MethodHandler {//…// 执行Handler 的处理
      public Object invoke(Object[] argv) throws Throwable {RequestTemplate requestTemplate = this.buildTemplateFromArgs.create(argv);Retryer retryer = this.retryer.clone();while(true) {try {return this.executeAndDecode(requestTemplate);} catch (RetryableException var5) {//…省略不相干代码}}
      }//执行请求,然后解码结果
      Object executeAndDecode(RequestTemplate template) throws Throwable {Request request = this.targetRequest(template);long start = System.nanoTime();Response response;try {response = this.client.execute(request, this.options);response.toBuilder().request(request).build();}
      }
      }
      
    4. SynchronousMethodHandler的invoke方法,调用了自己的executeAndDecode()请求执行结果解码方法

      1. 首先通过RequestTemplate请求模板实例,生成远程URL请求实例request
      2. 然后用自己的feign客户端client成员,execute()执行请求,并且获取response响应
      3. 对response响应进行结果解码
  11. Feign客户端组件feign.Client

    1. 客户端组件是Feign中一个非常重要的组件,负责端到端的执行URL请求,其核心逻辑:发送request请求到服务器,并接收response响应后进行解码

    2. feign.Client类,是代表客户端的顶层接口,只有一个抽象方法

    3. public interface Client {//提交HTTP请求,并且接收response响应后进行解码Response execute(Request request, Options options) throws IOException;}
      
    4. 由于不同的feign.Client实现类,内部完成HTTP请求的组件和技术不同,因此,feign.Client有多个不同的实现,

      1. Client.Default类:默认的feign.Client客户端实现类,内部使用HttpURLConnection完成URL请求处理
      2. ApacheHttpClient类:内部使用Apache httpclient开源组件完成URL请求处理的feign.Client客户端实现类
      3. OkHttpClient类:内部使用OkHttp3开源组件完成URL请求处理的feign.Client客户端实现类
      4. LoadBalancerFeignClient类:内部使用Ribbon负载均衡技术完成URL请求处理的feign.Client客户端实现类
  12. Client.Default类:

    1. 作为默认的Client接口实现类,在Client.Default内部使用JDK自带的HttpURLConnection类实现URL网络请求
    2. 在JDK1.8中,虽然在HttpURLConnection底层,使用了非常简单的HTTP连接池技术,但是其HTTP连接的复用能力,实际是非常弱的,性能当然也很低
  13. ApacheHttpClient类

    1. ApacheHttpClient客户端类的内部,使用Apache HttpClient开源组件完成URL请求的处理
    2. 从代码开发的角度而言,Apache HttpClient相比较传统JDK自带的URLConnection,增加了易用性和灵活性,他不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口,即提高了开发效率,也方便提高代码的健壮性
    3. 从性能角度而言,ApacheHttpClient带有连接池的功能,具备优秀的HTTP连接的复用能力
    4. ApacheHttpClient类处于feign-httpclient的专门的jar包中,如果使用,还需要通过Maven依赖或者其他的方式,导入配套版本的专门的jar包
  14. OkHttpClient类

    1. OkHttpClient客户端类的内部,使用OkHttp3开源组件完成URL请求处理,OkHttp3开源组件由Square公司开发,用于替代HttpUrlConnection和ApacheHttpClient,由于OkHttp3较好的支持SPDY协议(SPDY是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验),从Android4.4开始,google已经开始将Android源码中的HttpURLConnection请求类使用OkHttp进行了替换,也就是说,对于Android移动端APP开发来说,OkHttp3组件,世纪初的开发组件之一
  15. LoadBalancerFeignClient

    1. LoadBalancerFeignClient内部使用了Ribbon客户端负载均衡技术完成URL请求处理,在原理上,简单的使用了delegate包装代理模式,Ribbom负载均衡组件计算出合适的服务端server后,由内部包装类delegate代理客户端完成到服务端server的HTTP请求,所封装的delegate客户端代理实例的类型,可以是Client.Default默认客户端,也可以是ApacheHttpClient客户端类或OkHttpClient高性能客户端类,还可以其他的定制的feign.Client客户端实现类型
  16. Feign远程调用的执行流程

    1. 由于Feign远程调用接口的JDK Proxy实例的InvokeHandler调用处理器有很多种,导致Feign远程调用的执行流程,也稍微有所区别,但是远程调用执行流程的主要步骤,是一致的
    2. 与FeignInvocationHandler相关的远程调用执行流程
      1. FeignInvocationHandler是默认的调用处理器,如果不对Feign做特殊的配置,则Feign将使用此调用处理器,
      2. 第一步:通过Spring IOC容器实例,装配代理实例,然后进行远程调用
        1. Feign在启动时,会为加上了@FeignClient注解的所有远程接口,创建一个本地JDK Proxy代理实例,并注册到Spring IOC容器
        2. 然后本实例的controller代用代码中,通过@Resouce注解,按照类型或者名称进行匹配,从Spring IOC容器找到这个代理实例,并且装配给@Resource注解所在的成员变量,调用JDK Proxy动态代理实例的比如hello()方法
      3. 第二步:执行InvokeHandler调用处理器的invoke方法
        1. JDK Proxy动态代理实例的真正的方法调用过程,具体是通过InvkeHandler调用处理器完成的,所以这里的clientProxy代理实例,会调用到默认的FeignInvocationHandler调用处理器实例的invoke方法
        2. 默认的调用处理器FeignInvocationHandler,内部保持了一个远程调用方法实例和方法处理器的一个key-value键值对的Map映射,FeignInvocationHandler在其invoke方法中,会根据java反射的方法实例,在dispatch映射对象中,找到对应的MethodHandler方法处理器,然后由后者完成实际的HTTP请求和结果的处理
        3. 所以,FeignInvocationHandler会从自己的dispatch映射中,找到hello()方法所对应的MethodHandler方法处理器,然后调用invoke方法
      4. 第三步:执行MethodHandler方法处理器的invoke方法
        1. feign默认的方法处理器为SynchronousMethodHandler,其invoke方法主要是通过内部成员feign客户端成员client,完成远程URL请求执行和获取远程结果
        2. feign.Client客户端有多种类型,不同的类型,完成URL请求处理的具体方式不同
      5. 第四步:通过feign.Client客户端成员,完成远程URL请求执行和获取远程结果
        1. 如果MethodHandler·方法处理器实例中declient客户端,是默认的feign.Client.Default实现类,则使用JDK自带的HttpURLConnection类,完成远程URL请求执行和获取远程结果
        2. 如果MethodHandler方法处理器实例中的client客户端,是ApacheHttpClient客户端实现类,则使用ApacheHttpClient开源组件,完成远程URL请求执行和获取远程结果
    3. SynchronousMethodHandler并不是直接完成远程URL的请求,而是通过负载均衡机制,定位到合适的远程server服务器,然后再完成真正的远程URL请求,换句话说,SynchronousMethodHandler实例的client成员,其实例不是feign.Client.Default类型,而是LoadBalancerFeignClient客户端负载均衡类型,因此,上面的第三步:如果进一步细分的话,大致如下:
      1. 首先通过SynchronousMethodHandler内部的client实例,实质为负责客户端负载均衡LoadBalancerFeignClient实例,首先查找到远程的server服务端,
      2. 然后再由LoadBalancerFeignClient实例内部包装的feign.Client.Default内部类实例,去请求server端服务器,完成URL请求处理
    4. 默认的FeignInvocationHandler相关的远程调用执行流程,在运行机制以及调用性能上,满足不了生产环境的要求
      1. 没有远程调用过程中的熔断检测和恢复机制
      2. 也没有用到高性能的HTTP连接池技术

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30258.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3 之 Pinia 服务端渲染 (SSR) (九)

Pinia SSR概述 Pinia是一个用于Vue.js的状态管理库&#xff0c;它支持服务端渲染(SSR)。在SSR中&#xff0c;页面在服务器端渲染成HTML字符串&#xff0c;然后发送到客户端&#xff0c;从而提升首屏加载速度和SEO优化。Pinia通过其设计使得在SSR环境下也能轻松使用和管理状态。…

WiFi/BLE芯片(1):英飞凌

前言: 大部分客户很少直接接触到WiFi/Bluetooth的芯片,一般是直接封装到了模块中,隔了一层。具体到芯片而言,WiFi/BLE芯片,芯片厂家有:Qualcomm高通、broadcom博通、Infineon英飞凌、Nordic诺迪科、Espressof乐鑫等。而英飞凌这块产品也是很丰富的,低功耗、距离等性能指…

飞创直线模组厂家,为高精度运动系统提供直驱技术解决方案

飞创Faster motion是国内一家专业的直线模组厂家&#xff0c;致力于研发、设计、生产超长行程、超高速度、超高精度、超重负载以及速度平稳的单轴和多轴直线电机模组&#xff0c;为高速、高精度运动平台提供直驱技术解决方案。 飞创直线模组其生产的单轴、双轴、龙门、多轴模组…

Spring Boot究竟是如何进行自动配置的!

我们都知道 SpringBoot 是要比原始的 SpringMVC 这些好用的&#xff0c;毕竟如果经历过最早的 SSM 模式的开发的话&#xff0c;一定对那些大批量的繁琐的配置文件印象颇深&#xff0c;因为之前使用 SSM 框架来进行开发的时候&#xff0c;那配置文件多的让人心态都容易崩溃&…

化工电力系统RFID无线测温技术的重要性。

在现代工业体系中&#xff0c;化工电力系统的安全与效率对于整个生产链的顺畅运行至关重要。在日常工作中,由于设备制造的原因,设备受环境污染的原因、设备长期运行、严重超载运行、触点氧化、电弧冲击等原因造接触电阻增大,因此在运行时往往不断发热,温度不断上升,给设备安全运…

Leetcode Hot100之双指针

1. 移动零 题目描述 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。解题思路 双指针遍历一遍即可解决: 我们定义了两个指针 i 和 j&#xf…

C++ Windows Hook使用

GitHub - microsoft/Detours: Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form. /*挂载钩子 setdll /d:C:\Users\g\source\repos\LotTest\Release\lotDll.dll C:\Users\g\source\repos\LotTest…

Java特性之设计模式【访问者模式】

一、访问者模式 概述 在访问者模式&#xff08;Visitor Pattern&#xff09;中&#xff0c;我们使用了一个访问者类&#xff0c;它改变了元素类的执行算法。通过这种方式&#xff0c;元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式&…

WPF三方UI库全局应用MessageBox样式(.NET6版本)

一、问题场景 使用HandyControl简写HC 作为基础UI组件库时&#xff0c;希望系统中所有的MessageBox 样式都使用HC的MessageBox&#xff0c;常规操作如下&#xff1a; 在对应的xxxx.cs 顶部使用using 指定特定类的命名空间。 using MessageBox HandyControl.Controls.Message…

js语法---理解反射Reflect对象和代理Proxy对象

Reflect 基本要点 反射&#xff1a;reflect是一个内置的全局对象&#xff0c;它的作用就是提供了一些对象实例的拦截方法&#xff0c;它的用法和Math对象相似&#xff0c;都只有静态方法和属性&#xff0c;同时reflect也没有构造器&#xff0c;无法通过new运算符构建实例对象&…

xcode和iPhone真机或者watch真机连接问题

1.如果真机是第一次连接xocde&#xff0c;就需要开启真机上的开发者模式&#xff0c;开启开发者模式的方式&#xff1a; iphone/ipad开启方式: 设置 > 隐私与安全 > 开发者模式 > 开启&#xff0c;然后重启就可以了 watch设置&#xff1a;很麻烦&#xff0c;看文章…

数据库异常数据恢复(1)-快速恢复和镜像恢复

(一) 数据库服务器的崩溃和恢复 1. 服务器的修复机制 数据库因为某些原因导致数据库突然异常donw机&#xff0c;为了保证数据库的使用&#xff0c;提供了一些机制进行数据库的恢复 快速恢复&#xff1a;数据库异常down机后重启数据库自己的恢复方式&#xff0c;人工无法干预…

现代谱估计分析信号的功率谱(1)---AR 模型谱估计

本篇文章是博主在通信等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对通信等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在通信领域笔记&#xff1a;…

Spring相关面试题(一)

Spring 1.谈谈你对Spring的理解 难度系数 Spring 是一个开源框架&#xff0c;为简化企业级应用开发而生。Spring 可以是使简单的JavaBean 实现以前只有EJB 才能实现的功能。Spring 是一个 IOC 和 AOP 容器框架。 Spring 容器的主要核心是&#xff1a; 控制反转&#xff08;…

进阶篇06——锁

概述 全局锁 表级锁 表锁 元数据锁 元数据锁是系统自动加的&#xff0c;不需要我们手动执行命令添加。 意向锁 意向锁和元数据锁一样&#xff0c;也是在加行锁的时候自动给表加上相应的意向锁&#xff0c;不需要我们手动添加。 行级锁 行锁 读锁和读锁兼容&#xff0c;写锁…

易舟云财务软件:开启云记账新时代

在数字化浪潮的推动下&#xff0c;财务管理正经历着深刻的变革。易舟云财务软件&#xff0c;作为一款引领时代的云记账平台&#xff0c;以其卓越的功能和便捷的操作&#xff0c;为企业带来了全新的财务管理体验。 云记账&#xff0c;财务管理的未来趋势 云记账&#xff0c;即基…

免费试用【汇通动态域名】体验test.htdns.cn

汇通动态域名下载地址&#xff1a; http://www.htsoft.com.cn/htsoft/htdnssoft.html 下载后汇通动态域名是绿色软件&#xff0c;不用安装&#xff0c;直接运行htdns.exe 点注册 二级域名地方改成您自己要的域名&#xff0c;我输入的是test,点保存&#xff0c;提示让您输入密…

2024年618成交额达7428亿 淘宝京东618交易额数据对比排名

2024年618年中大促已经基本落下帷幕&#xff0c;作为上半年最重要的电商节日&#xff0c;今年的618交易额有多少&#xff1f;今年的交易数据有哪些变化&#xff1f;我们来一起看一下&#xff01; 根据星图监测数据显示&#xff0c;2024年618期间&#xff08;天猫5月20日20: 00-…

Python 中的 Pandas(数据分析与处理)

Pandas 是 Python 中最受欢迎的数据处理库之一&#xff0c;其名字源自于“Panel Data”&#xff08;面板数据&#xff09;的缩写。它提供了三种主要的数据结构&#xff1a;Series &#xff0c; DataFrame &#xff0c; Panel&#xff08;在新版本已经被弃用&#xff09; 数…

海外盲盒APP开发,盲盒出海热!

当下&#xff0c;盲盒作为一种热门的娱乐休闲模式&#xff0c;在全球消费市场中都非常火热&#xff0c;各种热门盲盒商品刚一上线就受到了秒杀&#xff0c;受到了各地年轻消费者的追捧&#xff01; 盲盒全球化对于我国盲盒企业来说是一个新的机会&#xff0c;有助于我国盲盒快…