1.【SpringCloud原理】OpenFeign原来是源码这么基于Ribbon来实现负载均衡的
2.SpringCloud 微服务接口调用组件 - OpenFeign 简介
3.Spring Cloud 2022 正式发布!我的源码天,OpenFeign 要退出历史舞台了?!源码
4.Spring Cloud OpenFeign源码FeignClientFactoryBean原理
【SpringCloud原理】OpenFeign原来是源码这么基于Ribbon来实现负载均衡的
大家好,本文将深入探讨 SpringCloud 组件原理,源码特别是源码独立行情指标源码 OpenFeign 如何基于 Ribbon 实现负载均衡的机制。在此前的源码文章中,我们已详细解析了 OpenFeign 动态代理生成原理及 Ribbon 运行机制,源码如需回顾相关知识,源码欢迎关注微信公众号 “三友的源码java日记”,通过菜单栏查看整理内容。源码接下来,源码我们将进一步揭示 OpenFeign 与 Ribbon 如何协同工作,源码实现高效负载均衡。源码一、源码Feign 动态代理调用实现 rpc 流程分析
通过了解 Feign 客户端接口的动态代理生成原理,我们得知动态代理基于 JDK 的机制实现,所有方法调用最终通过 InvocationHandler 接口的 ReflectiveFeign.FeignInvocationHandler 实现。接下来,我们将探讨 FeignInvocationHandler 如何执行 rpc 调用。 FeignInvocationHandler 中的 invoke 方法实现关键步骤如下:前几行判断方法是否为 equals、hashCode、toString 等不需要走 rpc 调用的特殊方法。
从 dispatch 获取对应方法的 MethodHandler,然后调用 MethodHandler 的 invoke 方法。MethodHandler 的生成发生在构建动态代理时。
MethodHandler 是接口的实现类,分为 DefaultMethodHandler(处理接口默认方法)和 SynchronousMethodHandler(实现 rpc 调用)。我们接下来关注 SynchronousMethodHandler 中的 invoke 方法实现。 SynchronousMethodHandler 的 invoke 方法包含关键步骤:构建 RequestTemplate,用于封装构建 HTTP 请求所需的ddx连续飘红指标源码参数,如头信息和 body 等。
调用 findOptions(argv) 方法获取连接超时时间和读超时时间配置。如果没有配置,将使用构建 SynchronousMethodHandler 时传入的参数。
执行重试组件(通常不设置重试逻辑)。
执行 executeAndDecode(template, options),进入此方法后执行 targetRequest,遍历所有请求拦截器(Feign 的扩展点),允许在发送请求前进行参数调整,如添加请求头,这在微服务间鉴权时常用。
之后,构造请求并调用 Client 接口的 execute 方法发送请求,接收响应,并将响应数据封装为所需参数返回给调用方。二、LoadBalancerFeignClient
在理解整个动态代理调用流程后,我们发现关键在于 Client 接口的实现,负责发送 HTTP 请求。那么,Client 是什么?在关于 OpenFeign 动态代理生成的文章中,我们探讨了 Feign 在构建动态代理时填充组件到 Feign.Builder 的过程,其中包含 Client 的实现,但并未在 FeignClientsConfiguration 配置类中找到 Client 对象的声明。这提示我们,Client 实现依赖于负载均衡,是 Feign 整合 Ribbon 的入口。 接下来,我们将聚焦于 Client 的实现,特别是仿w3c源码 Feign 如何利用 Ribbon 实现负载均衡。 首先,我们查看 Feign 与 Ribbon 整合的配置类,该类导入了关键配置类。其中,DefaultFeignLoadBalancedConfiguration 配置类声明了 LoadBalancerFeignClient 到 Spring 容器中,传入了 Client 实现、CachingSpringLoadBalancerFactory 和 SpringClientFactory。 LoadBalancerFeignClient 实现了 Client 接口,构建 Feign.Builder 时注入的是这个对象。接下来,我们深入分析构造 LoadBalancerFeignClient 的实现流程。 动态代理调用过程中得出结论,最终会调用 Client 接口的 execute 方法,因此,我们关注 execute 方法的实现。此方法包含一系列操作,从请求 URL 中获取 clientName(服务名),并利用 OpenFeign 构建动态代理时传入的 HardCodedTarget 从 URL 中提取服务名。获取服务名后,LoadBalancerFeignClient 调用 lbClient 方法。 lbClient 方法实现关键步骤,首先从缓存中获取或创建 FeignLoadBalancer,然后利用 CachingSpringLoadBalancerFactory 的 create 方法构建 FeignLoadBalancer。 FeignLoadBalancer 实现关键逻辑,调用 executeWithLoadBalancer 方法处理请求,接收 Response 后直接返回。三、FeignLoadBalancer
FeignLoadBalancer 是关键组件,负责负载均衡和 HTTP 请求的发送。它继承 AbstractLoadBalancerAwareClient,一起点源码实现了核心功能。 FeignLoadBalancer 的 execute 方法包含关键步骤,直接定位到核心代码行,request.client() 获取注入的 Client 实现,即 Client.Default 类或基于 HttpClient 或 OkHttp 的实现。调用此行代码成功发送 HTTP 请求,接收响应后封装成 RibbonResponse,最终返回给 MethodHandler,解析响应并封装为方法的返回值。总结
通过本文,我们完整解析了 OpenFeign、Ribbon 和 Nacos(或其他注册中心)协同工作原理,涵盖五个关键组件的源码和流程。简而言之,OpenFeign 在进行 rpc 调用时,由于服务所在机器未知,Ribbon 负责从机器列表中选择一个,该列表由注册中心提供。Ribbon 的 ServerList 接口允许注册中心实现,获取服务机器列表。通过这三个组件的协同作用,实现了微服务架构中的高效负载均衡。 本文旨在帮助读者了解微服务架构的基本原理,同时深入理解 OpenFeign、Ribbon 和 Nacos 的源码。如有疑问或交流需求,欢迎关注微信公众号 “三友的java日记” 或添加微信 ZZYNKXJH 联系作者。感谢阅读,期待与您在下篇文章中相遇。SpringCloud 微服务接口调用组件 - OpenFeign 简介
本文是万人迷源码SpringCloud专栏的开篇之作,将逐步分享在实际工作中运用到的微服务组件及填坑经验,以期对大家有所帮助,减少踩坑的次数。
专栏所采用的版本为SpringCloud .0.5及SpringBoot 2.5.0。
OpenFeign是声明式的Rest接口客户端,相当于HttpClient,用于实现服务接口的远程调用。假设集群中有服务A和B,通过OpenFeign注解,服务A可以自动调用服务B的远程Rest接口,如同调用本地方法。
示例代码中,通过Spring中获取Bean并调用getReviewerIds方法,即可请求远程服务AUTH的Rest接口。
具体实例可参考官网提供的Feign Using Eureka示例。
采用OpenFeign的原因在于它封装了Feign与RestTemplate,支持SpringMVC注解与消息转换器,结合SpringMVC定义的Controller注解,如@GetMapping、@PathVariable等,唯一区别在于当以Get方式传递Pojo对象时,提供了新的注解@SpringQueryMap。
在SpringCloud .x版本中,已移除了ribbon的负载均衡功能,改为使用SpringCloud-LoadBalance实现。
@FeignClient配置简介,其源码显示默认配置为FeignClientsConfiguration。配置方式一中,@FeignClient注解的configuration属性默认值为FeignClientsConfiguration,实际是通过@ConditionalOnMissingBean定义相关Bean。自定义配置类无需添加@Configuration注解,以免影响全局应用。
配置方式二允许在配置文件中进行设置,配置文件优先级高于配置类,同时设置@FeignClient的configuration和配置文件时,配置文件优先。
OpenFeign实现原理基于代理机制,通过自定义接口方法实现远程服务调用,且通过注册中心存储服务提供者信息,如集群数、实例IP和端口等。
@FeignClient接口推荐在消费端实现,以便于维护和避免代码冗余。然而,不同的观点倾向于将此类放置在服务端。对于引入OpenFeign带来的问题,学习研究新组件和分布式事务问题成为首要挑战。
OpenFeign使用简单,后续文章将探讨生产环境中使用OpenFeign遇到的问题及解决方案。
Spring Cloud 正式发布!我的天,OpenFeign 要退出历史舞台了?!
大家好,我是栈长。
今天给大家通报一则框架更新消息,时隔 .x 版本发布一年,Spring Cloud .0.0 最新版发布了,来看下最新的 Spring Cloud 版本情况:
Spring Cloud 无疑是现在 Java 微服务事实上的标准,完全基于 Spring Boot 构建,依赖 Spring 生态体系,可以很好的与各种 Spring 生态项目无缝对接。
Maven 依赖先给大家奉上:
Spring Cloud 依赖管理采用的是 import 导入方式,里面管理了许多依赖,统一引入管理,使用时只需要引入对应依赖的坐标即可,不需要指定版本号。
Spring Cloud 目前维护着 4 条版本主线:
关于这些版本线的命名是不是很奇怪?
另外,还有几天都要 年了,怎么现在才发布 版本?
其实 Spring Cloud 最新的版本命名方式早已经变更了,以后就是YEAR.x 这种命名方式了,不清楚的可以看下栈长之前写的两篇文章:
所以说,Spring Cloud .0.0 中的 是指 Spring Cloud .x 版本线,.0.0 则是指 这个版本线的第 1 个版本,而不是指某个年份发布的版本。
新特性解读
Spring Cloud .0.0 是一个大版本,更新了太多内容,栈长不打算全部解读,说几个有意思的更新吧。
完整特性更新参考官方发布文档:
1、系统环境
Spring Cloud .0.0 基于以下环境进行构建:
所以,这也是 Spring Cloud .0.0 的最低依赖要求,升级请小心。
2、模块升级
3、Eureka 已经更新到 Eureka 2.0.0
大家都知道 Eureka 2.x 早已经停止维护了,如该分支最新公告所示:
github.com/Netflix/eure...
虽然 Eureka 2.0.0 是 Eureka 的一个新分支,但这个分支与 7 年前的 2.x-archive 旧实验分支无关。
创建 Eureka 2.x 新分支的目的是为了与 JakartaEE 兼容而已,让 Spring Cloud Netflix 可以兼容 Spring Framework 6.0 和 Spring Boot 3.0,仅此而已。
4、Spring Cloud OpenFeign 功能完成公告
由于 Spring 现在提供了自己的 HTTP 接口客户端解决方案,比如在最新的 Spring Boot 3.0 中实现接口调用可以有以下两种解决方案:
所以,从 Spring Cloud .0.0 版本开始,Spring Cloud OpenFeign 模块已经视为功能完成状态了,这意味着 Spring Cloud 团队将不再向该模块添加新功能。
虽然 OpenFeign 不会再添加新功能,但还是会继续修复错误和安全问题,并且也还会考虑和审查来自社区的小规模的 pull requests 请求。
这是不是意味着,在不久的将来,OpenFeign 要退出历史舞台了?
Spring Cloud 支持版本
Spring Cloud 支持的版本情况,以及对应的 Spring Boot 版本如下表所示。
需要注意的是: 正常维护中的版本中有 Spring Cloud + 了,其他的版本已经彻底结束生命周期了,官方不再提供维护支持了,非必要,尽量不要再使用了。
目前最新的 Spring Cloud Alibaba .0.4.0 还是基于 Spring Cloud .0.4.0,尚未同步更新最新的 Spring Cloud .0.0 版本,这个在栈长的微服务课程中也有说明了,两者的版本不一定完全同步,也可能会跳过。
总结
Spring Cloud .0.0 是一个革命性的大版本,依赖的系统环境和模块都有大幅度的更新,特别是 JDK 、Spring 基础框架的最低要求,对于想升级的小伙伴来说无疑是一件难事,国内的应用也都还是以 JDK 8 为主,要迁移到 Spring Cloud 版本恐怕还需要不少的时日。
Spring Boot 理论和实战源码仓库:
github.com/javastacks/s...
你们用的哪个 Spring Cloud 版本呢?欢迎留言分享~
好了,今天的分享就到这里了,后面栈长我会更新更多好玩的 Java 技术文章和最新的技术资讯,关注Java技术栈第一时间推送,不要走开哦。
版权声明: 本文系 "Java技术栈" 原创,原创实属不易,转载、引用本文内容请注明出处,抄袭者一律举报+投诉,并保留追究其法律责任的权利。
Spring Cloud OpenFeign源码FeignClientFactoryBean原理
Spring Cloud OpenFeign的FeignClientFactoryBean在实例化过程中,通过FactoryBean接口实现,GetObject方法的关键步骤包括获取FeignContext、配置Feign.Builder、创建HardCodedTarget和调用loadBalance方法。这些步骤涉及自动配置、FeignClientSpecification的使用、Logger和Builder组件的定制以及动态代理的生成。最后,getObject方法返回的是一个接口的代理类,用于执行远程调用。
详细分析:
FeignClientFactoryBean在Spring容器中,通过getObject方法转化为实际的FeignClient实例。首先,它从FeignContext获取相关配置,这个配置在引入OpenFeign依赖时自动注入。接下来,通过getTarget方法,FeignClientFactoryBean配置了Builder组件,如Logger(非Slf4j)、RequestInterceptor、Encoder和Decoder等,同时考虑了用户自定义组件的配置。之后,创建了HardCodedTarget,基于FeignClient接口、注解值和完整URL构建,然后通过loadBalance方法,整合了LoadBalancerFeignClient和HystrixTargeter,进行负载均衡和目标URL定位。
在newInstance方法中,解析了接口方法的注解,生成了MethodHandler,并用FeignInvocationHandler封装,这个InvocationHandler在代理类实例化时被调用,实现了远程调用。最终,通过Proxy.newProxyInstance动态生成了代理类,完成FeignClientFactoryBean的实例化过程。
总的来说,FeignClientFactoryBean实例化是通过一系列配置和代理生成,实现了Spring Cloud OpenFeign的远程调用功能。如果你对源码的深入理解感兴趣,下期文章将继续解析调用源码细节。