当前位置:首页 > 数码 > OpenFeign-解说-全网最具体的 (openfeign底层实现原理)

OpenFeign-解说-全网最具体的 (openfeign底层实现原理)

admin4个月前 (05-09)数码32
OpenFeign是一个十分有用的工具,它为开发者提供了一种繁难而弱小的模式来处置远程服务调用。经过经常使用OpenFeign,开发者可以专一于业务逻辑,而无需破费太多精神在复杂的网络编程细节上。

环境:SpringCloud3.1.5

1.简介

SpringCloudOpenFeign是一种申明式、模板化的HTTP客户端,它简化了远程调用的编程体验。在SpringCloud中经常使用OpenFeign,开发者可以像调用本地方法一样经常使用HTTP恳求访问远程服务,而无需感知这是在调用远程方法。

OpenFeign会依据带有注解的函数信息构建出网络恳求的模板,在发送网络恳求之前,OpenFeign会将函数的参数值设置到这些恳求模板中。

在名目启动阶段,OpenFeign框架会智能的扫包流程,从指定的目录下扫描并加载一切被@FeignClient注解润色的接口。OpenFeign会针对每一个FeignClient接口生成一个灵活代理(JDK)对象,这个灵活代理对象会被参与到Spring高低文中,并注入到对应的服务里。

总的来说,SpringCloudOpenFeign是一种弱小的工具,它可以协助开发者更轻松地成功微服务的远程调用。

2.OpenFeign性能

2.1开启性能

引入依赖

groupId:org.springframework.cloudartifactId:spring-cloud-starter-openfeign

开启

@SpringBootlication@EnableFeignClientspublicclassDemoApplication{publicstaticvoidmn(String[]args){SpringApplication.run(DemoApplication.class,args);}}

示例

@FeignClient(name="demoService")publicinterfaceDemoFeign{@GetMapping("/info/{id}")publicObjectinfo(@PathVariable("id")Integerid);}

在@FeignClient注解中,name="demoService"是一个客户端称号,用于创立SpringCloudLoadBalancer客户端。你也可以设置url属性(相对值或主机名)指定一个URL。

2.2自定义性能

经过指定@FeignClientconfiguration属性成功自定义性能

@FeignClient(name="demoService",configuration=DemoConfiguration.class)publicinterfaceDemoFeign{}

自动状况下SpringCloudOpenFeign会提供如下的自动Bean:

DecoderfeignDecoder:ResponseEntityDecoder照应内容解码

EncoderfeignEncoder:SpringEncoder

LoggerfeignLogger:Slf4jLogger

MicrometerCapabilitymicrometerCapability:假设feign-micrometer位于类门路上,且MeterRegistry可用

CachingCapabilitycachingCapability:假设经常使用@EnableCaching注解。可经过feign.cache.enabled封锁。

ContractfeignContract:SpringMvcContract这个的作用就是用来接下@FeignClient注解类中的相应MVC注解

Feign.BuilderfeignBuilder:FeignCircuitBreaker.Builder构建Feign客户端的,比如环境中经常使用了CircuitBreaker,那么就会在调用接口时运行断路器性能

ClientfeignClient:假设SpringCloudLoadBalancer位于类门路上,则经常使用FeignBlockingLoadBalancerClient。假设它们都不在类门路上,则经常使用自动的FeignClient。自动的Client经常使用jdk自定的网络恳求URLConnection。

咱们可以在自定义的DemoConfiguration中自定义自己的成功,在DemoConfiguration中你可以自定义如下的Bean:留意:这些bean是OpenFeign没有提供的,除了上方引见的你可以笼罩自定义成功,你还可以定义上方的bean

Logger.LevelRetryerErrorDecoderRequest.OptionsCollection<RequestInterceptor>SetterFactoryQueryMapEncoderCapability(MicrometerCapabilityandCachingCapabilityareprovidedbydefault)

接上去会引见罕用的一些自定义性能

@FeignClient(name="${pack.demo.name}",)publicinterfaceDemoFeign{}

性能文件

pack:demo:name:demoServiceurl:
feign:client:config:default:connectTimeout:5000readTimeout:5000

自动一切的接口恳求超时都是5s。

假设启用了Feign客户端刷新,则每个Feign客户端都会以feign.Request.Options作为refresh-scopedBean来创立。这象征着connectTimeout和readTimeout等属性可以经过POST/actuator/refresh针对任何Feign客户端实例启动刷新。值须要启动如下性能接口

openfeign底层实现原理
feign:client:refresh-enabled:true

性能文件中设置

logging:level:'[com.pack.feign.test.DemoFeign]':debug

性能日志基本,两种模式:1性能文件;2定义Bean

feign:client:config:demoService:logger-level:full

在自定义性能类中定义为bean

@BeanpublicLogger.LevelloggerLevel(){returnLogger.Level.FULL;}

自动状况下,当恳求的接口产生意外不会启动重试,可以经过定义上方bean启动重试

@BeanpublicRetryerfeignRetryer(){Retryer.Defaultretryer=newRetryer.Default(100,SECONDS.toMillis(1),2);returnretryer;}

自动OpenFeign不提供任何阻拦器,假设你须要在恳求行启动处置,比如参与恳求header,那么你可以自定义阻拦器成功

@BeanpublicRequestInterceptorheaderRequestInterceptor(){returntemplate->{template.header("X-API-TOKEN","666666");};}

也可以经过性能文件性能

feign:client:config:demoService:request-interceptors:-com.pack.feign.HeaderRequestInterceptor

在某些状况下,或者须要自定义Feign客户端,你可以经常使用FeignBuilderAPI创立客户端。上方的示例创立了两个具备相反接口的FeignClient,但每个客户端都性能了独自的恳求阻拦器。

publicclassDemoController{privateDemoFeigndemoFeign;@AutowiredpublicDemoController(Clientclient,Encoderencoder,Decoderdecoder){this.fooClient=Feign.builder().client(client).encoder(encoder).decoder(decoder).requestInterceptor(newHeaderRequestInterceptor("X-API-TOKEN","666666")).target(FooClient.class,"http://localhost:8088/demos");}}

当你的类门路下有了SpringCloudCircuitBreaker后服务升级fallback才会失效。

@FeignClient(url="http://localhost:8088/demos",name="demoService",configuration=DemoFeignConfiguration.class,fallback=DemoFeignFallback.class)publicinterfaceDemoFeign{@GetMapping("/info/{id}")publicObjectinfo(@PathVariable("id")Integerid);}

服务升级类必定成功对应FeignClient的接口

publicclassDemoFeignFallbackimplementsDemoFeign{publicObjectinfo(Integerid){return"default-"+id;}}

假设须要访问触发回退的要素,可以经常使用@FeignClient内的fallbackFactory属性。

@FeignClient(url="http://localhost:8088/demos",name="demoService",configuration=DemoFeignConfiguration.class,fallbackFactory=DemoFeignFallbackFactory.class,)publicinterfaceDemoFeign{@GetMapping("/info/{id}")publicObjectinfo(@PathVariable("id")Integerid);}

工厂类

publicclassDemoFeignFallbackFactoryimplementsFallbackFactory<DemoFeignFallback>{staticclassDemoFeignFallbackimplementsDemoFeign{privateThrowablecause;publicDemoFeignFallback(Throwablecause){this.cause=cause;}@OverridepublicObjectinfo(Integerid){return"接口调用意外-"+this.cause.getMessage();}}@OverridepublicDemoFeignFallbackcreate(Throwablecause){returnnewDemoFeignFallback(cause);}}

假设经常使用@EnableCaching注解,则会创立并注册一个CachingCapabilityBean,以便Feign客户端识别其接口上的@Cache*相关注解:

@FeignClient(url="http://localhost:8088/demos",name="demoService",configuration=DemoFeignConfiguration.class,fallbackFactory=DemoFeignFallbackFactory.class,)publicinterfaceDemoFeign{@GetMapping("/info/{id}")@Cacheable(cacheNames="demo-cache",key="#id")publicObjectinfo(@PathVariable("id")Integerid);}

Feign经过单承袭接口支持模板运行程序。这样就可以将罕用操作归类到繁难的基础接口中。

@FeignClient(url="http://localhost:8088/users",name="userService")publicinterfaceUserService{@GetMapping("/{id}")UsergetUser(@PathVariable("id")Longid);}@FeignClient("users")publicinterfaceUserClientextendsUserService{}

留意:@FeignClient接口不应在主机和客户端之间共享,并且不再支持在类级经常使用@RequestMapping对@FeignClient接口启动注解。

你可以思考为你的Feign恳求启用恳求或照应GZIP紧缩。你可以启用其中一个属性:

feign:compression:requestenabled:trueresponse:enabled:true

控制紧缩MeidaType类型和最小恳求阈值长度

feign:compression:request:mime-types:text/xml,application/xml,application/jsonmin-request-size:2048

3.关于照应式客户端

由于OpenFeign名目目前不支持SpringWebClient等反响式客户端,因此SpringCloudOpenFeign也不支持反响式客户端。

目前官网介绍的照应式库:feign-reactive

<dependency><groupId>com.playtika.reactivefeign</groupId><artifactId>feign-reactor-webclient</artifactId><version>3.3.0</version></dependency>

我目前经常使用的是3.3.0版本,除了注解适当调整,其它经常使用基本分歧,十分爽。

@ReactiveFeignClient(url="http://localhost:8088/demos",name="demoReactorFeign",fallback=DemoReactorFeignFallback.class,configuration={DemoReactorFeignConfig.class})publicinterfaceDemoReactorFeign{@GetMapping("/info/{id}")publicMono<Object>info(@PathVariable("id")Integerid);}

总结:

OpenFeign是一个十分有用的工具,它为开发者提供了一种繁难而弱小的模式来处置远程服务调用。经过经常使用OpenFeign,开发者可以专一于业务逻辑,而无需破费太多精神在复杂的网络编程细节上。

OpenFeign的申明式编程格调使得咱们能够以一种高度形象和繁复的模式与远程服务启动交互,它简化了网络恳求的构建和发送环节,降落了开发的复杂度。

总的来说,SpringCloudOpenFeign是一个弱小而灵敏的工具,它可以协助开发者更高效地构建和保养微服务运行。经过经常使用OpenFeign,咱们可以更好地专一于业务逻辑,而无需担忧网络调用的成功细节。

终了!!!


如何阅读SpringCloudOpenFein源码?

阅读SpringCloudOpenFeign源码的方法有很多,这里提供一种方法:1.首先,需要了解SpringCloudOpenFeign的基本原理和功能。 可以通过阅读官方文档和相关博客来了解。 2.其次,需要下载SpringCloudOpenFeign的源码。 可以从GitHub上下载,也可以通过Maven或Gradle等构建工具来获取。 3.然后,需要了解SpringCloudOpenFeign的目录结构和代码结构。 可以通过阅读官方文档和相关博客来了解。 4.最后,需要逐个模块地阅读源码。 可以先从最基础的模块开始,逐步深入到其他模块。 在阅读过程中,可以使用调试器等工具来帮助理解代码逻辑。

spring boot Open Feign 客户端加载过程

关于Fegin,可以学习下面的文章 pmo引入 如果要跑起来的话,还需要consul 和 loadbalancer(Eureka,Ribbon的替代) spring boot 引入 用了@Import({}) 参照 spring boot Appollo加载过程 实现了3个接口 实现了:Specification的getConfiguration方法 Specification 是 NamedContextFactory类的内部接口 具体的流程后面再说,先看下它的定义,很简单 实现了: 这里有两个问题一个Client,一个Targeter 先看Client 所以无论走 if 还是 else 都是从context里取到Client 然后用创建 不指定url,用name到注册中心取地址,走负载均衡 指定url的时候走else,直接访问url,不走负载均衡 请注意这句,最终返回的对象,是根据Client造出来的 可以看到 Client 是从AnnotationConfigApplicationContext 里取出来的 但我们并没有配置或创建这个Bean 所以只有一种可能 通过@Configuration 创建出来的 找一下 在FeignLoadBalancerAutoConfiguration里发现了 一共引进了4个LoadBalancer 因为我们没做任何配置所以走DefaultFeignLoadBalancerConfiguration 这个我们没配 所以Client就是RetryableFeignBlockingLoadBalancerClient 再看Targeter 不罗嗦了,是在FeignAutoConfiguration里配的 这里同时还生产了很多类 其中FeignContext很重要,之后讲 没有或它为false时 返回DefaultTargeter 然后看Builder 的target了 来了 返回代理类 到此为止, Open Feign 的加载过程讲完了 但 还不够详细下面在补充点 之前提到了FeignContext 任何一段程序都是运行在一个上下文环境中的 所以看看它做了些什么 FeignContext是在FeignAutoConfiguration 里生产出来的 并传入了configurations:所有由@FeignClient注解的类 FeignContext 继承自:NamedContextFactory 构造函数里,给父类构造函数传了个 真正的配置都在FeignClientsConfiguration里 NamedContextFactory 构造函数并没有做什么 大家可以向上找,找到Client 的创建过程 里面的函数getContext 其中用到了 createContext:初始化 每个@FeignClient 的context 这句话注册了FeignClientsConfiguration 也就是说它会被spring容器管理并加载 好看看它都做了什么 FeignClientsConfiguration encode,decode什么的不说了 主要是feignContract方法 创建了SpringMvcContract Feign本身是由一套自己的注解的,但用了OpenFeign就可以直接使用springmvc的注解了 就是由这个类完成了转换 SpringMvcContract 继承自 实现了:ResourceLoaderAware 具体的实现我就不讲了,看下我列出来的两个方法 open feign 从3.0开始就不支持Ribbon

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: OpenFeign