窥探Open-Feign的核心原理

引言

上文我们讲述了整个Open-Feign的使用和大的思想,我们知道了整体是基于JDK的动态代理来实现的,而JDK动态代理的核心又是InvocationHandler,所以本章我们就从InvocationHandler入口来探索整个Open-Feign是如何实现远程调用的。

揭露Open-Feign的入口

当JDK动态代理对象调用方法时,会执行InvocationHandler的invoke方法,因此我们先要关注Open-Feign中构建动态代理的InvocationHandler具体实现,看源码会发现有两个实现:一个是FeignInvocationHandler,另一个是FeignCircuitBreakerInvocationHandler,两者的区别在于:

  1. 所属:FeignInvocationHandler是属于原生Feign的,而FeignCircuitBreakerInvocationHandler是Open-Feign新增的
  2. 功能:两者都能完成RPC的调用,FeignCircuitBreakerInvocationHandler是在FeignInvocationHandler的基础上封装了一层熔断降级的处理,即集成了CircuitBreaker的功能

可以说FeignCircuitBreakerInvocationHandler是FeignInvocationHandler的增强版,但整个RPC请求的核心功能都是一样的,本章我们基于FeignInvocationHandler来进行研究这一过程,如下:

探索Open-Feign的处理核心

在上图中,我们发现当请求调用FeignInvocationHandler的invoke方法后会调用到SynchronousMethodHandler的invoke方法,所以整个核心的处理逻辑就在此处了。

在查看Open-Feign的具体处理逻辑之前,我们可以自己先来想一想:我们要实现RPC调用,那么我们需要将我们要请求的信息封装成一个Http请求报文,然后通过Http客户端发起Http请求,然后接收响应进行处理;Open-Feign的处理逻辑也是这样,但是为了更好了理解Open-Feign的处理流程,我们熟悉下其中的一些概念:

1、相关概念

  1. Contract:用来解析标记@FeignClient接口中的所有与方法,输出MethodMetadata
  1. MethodMetadata:对应方法的元信息,是对执行方法的解析获取到的请求url和请求参数相关信息的封装,由Contract#parseAndValidateMetadata解析获取到
  2. RequestTemplate.Factory:会根据传入的请求参数args以及方法的元信息MethodMetadata转换成RequestTemplate
  1. RequestTemplate:是构建Http的Request的一个模板,其中包含了url,header,HttpMethod,body等相关信息
  2. Target:主要用于将RequestTemplate转换为Feign的feign.Request
  1. feign.Request:这是Feign对外的Http请求封装
  2. feign.Response:这是Feign对外的Http响应封装
  3. Client:Feign中定义对外的Http请求客户端规范:feign.Client,真正的Http客户端会以代理对象的形式组合到feign.Client的实现中
  1. Retryer:重试器,当Http请求执行失败且抛出可重试异常时重试器会进行重试
  2. RequestInterceptor:请求的拦截器,可以对RequestTemplate进行调整
  3. Encoder:请求的编码器
  4. Decoder:响应的解码器

2、核心处理流程

其实,当我们梳理清楚了上面的几个概念后,再来查看整个链路就很清晰了,Open-Feign实现RPC的整个执行逻辑如下图:

  1. 首先在构建动态代理的时候会通过Contract组件来帮我们构建出MethodMetadata
  2. 当请求来的时候RequestTemplate.Factory会通过请求参数args,MethodMetadata以及编码器Encoder来构建出RequestTemplate
  3. Target组件会将RequestTemplate转换成feign.Request,然后丢给Client进行Http请求
  4. 请求成功会返回feign.Response,并使用解码器对Response进行解码,返回想要的输出,从而完成一次请求

NOTE:其中,整个过程中如果发生可重试的异常且在重试的次数内就会发起请求重试

总结

这两篇文章,笔者主要聊了聊Open-Feign的使用和实现的思想和逻辑,并没有花太多的时间在源码上。因为笔者认为,思想相对于实现而言,思想更重要,实现可以有各种各样,但思想才是王道,它是你实现的宗旨,掌握了思想再去看那些实现会轻松很多,也会学到更多,希望与大家共勉!

另外,关于Open-Feign的熔断降级,负载均衡,以及具体HttpCllient的可插拔配置等等高级使用,我们后续慢慢来聊。

🙏 感谢您花时间阅读这篇文章!如果觉得有所收获,请关注我的更新,给个喜欢和分享,如果有任何疑惑,可以评论区交流。您的支持是我写作的最大动力!✍️🌟

相关推荐
2501_918582371 小时前
HarmonyOS应用开发实战:小事记 - Stage 模型下 EntryAbility 的启动流程与 Want 解析机制
后端
野蛮人6号1 小时前
黑马天机学堂Day01-08.搭建项目环境-本地开发部署方式——不知道nacos的密码是什么
java·spring cloud·黑马程序员·天机学堂·黑马天机学堂
名字还没想好☜1 小时前
Go 用 errgroup 管理并发子任务:错误收敛、取消传播与限流
开发语言·后端·golang·go·并发
星栈独行2 小时前
Node 框架怎么选?Express、Koa、Egg、NestJS 场景化选型指南
后端·程序人生·node.js
你为她披上外套时我正站在窗外3 小时前
拆解 siwi-download:Rust 异步下载器是怎么炼成的
后端
苍何3 小时前
WAIC深度体验:能跨端使用的 Agent 才是好 Agent!
后端
程序员清风3 小时前
推荐几个我常听的AI播客!
java·后端·面试
JavaGuide4 小时前
Kimi K3 实战:全栈项目、Java 项目改造与 3A 游戏 Demo
后端·ai编程
wuqingshun3141594 小时前
如何理解Spring Boot中的starter?
java·spring boot·后端
AskHarries4 小时前
PayPal 接入避坑
后端