携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
Feign介绍
Feign 微服务之间的调用方式,属于较轻量级的调用方式,可以通过注解来进行调用,请求模式也是基于模版化,传入参数封装成请求的模式。
远程调用主要是基于FeignClient注解作用在接口上,被标注的接口可以通过@Resource注入后使用,让Spring容器来管理。
@FeignClient注解属性如下: Name:指定调用服务的名称,通过服务名称发现服务。 Url:调用服务的地址。 Decode404:调用服务出现失败的时候如果该字段为true,会进行decoder解码,为false则抛出FeignException异常。 Configuration:定义feign的配置模式。 Fallback:定义feign接口请求失败的降级方法。 FallbackFactory:通过工厂类,来创建降级容错方法。 Path:定义当前FeignClient的统一前缀
具体请求步骤
Feign帮助我们做了些什么
Feign算做什么一个RPC框架,我们常见的RPC框架主要有Feign和Dubbo,Feign基于Ribbon构建RestTemplete是一种基于Http协议的RPC实现方式,而Dubbo则是基于私有的Tcp协议。
正如上面对Feign基介绍,Feign帮我简化了一个Http请求,直接通过接口的形式去请求环境上的服务。
Feign的基本原理
首先让我们剖析源码来看下,@EnableFeignClients注解到底是如何实现服务于服务之间的远程调用的。
FeignClients初始化
首先我们看@EnableFeignClients注解会有5个属性定义.
Value:需要我们指定具体调用的服务名称。
basePackages:用于扫描注释组件的基本包。Value()是此属性的别名(与之互斥),使用basepackageclass()作为基于string的包名的类型安全替代方案。
basePackageClasses:basePackages()的类型安全替代方案,用于指定要扫描注释组件的包。主要是需要考虑包下每一个类,除了被属性引用,不会被其他属性引用。
defaultConfiguration:默认加载的一些客户端组件,例如feign.codec。解码器,feign.codec。编码器,feign.Contract。
Clients:如果不进行配置,则默认使用@FeignClient标注的的类的列表。
我们看注解import的类FeignClientsRegistrar是用来初始化FeignClient配置 ,里面的registerDefaultConfiguration方法是用来加载@EnableFeignClients注解里configuration配置文件,通过Map接收EnableFeignClients注解的属性参数。
看到BeanDefinitionBuilder相信大家都不陌生,Spring通过BeanDefinition来构造Bean的配置信息。通过BeanDefinitionBuilder来构建FeignClientFactoryBean,里面的参数在上面Feign的属性已经介绍过了
FeignClientFactoryBean里面是由Feign.Builder、logger、encoder、decoder和contract。
这几个组件组成,encoder/decoder为数据格式转化的协议,logger接收日志,Feign 默认的contract协议
看到这里,我们仅仅是看到一个属性的初始化流程,还没有看到远程调用是如何进行的,我们接着看。
Ribbon构建请求
我们前面说Feign基于Ribbon构建RestTemplete,我们在spring-cloud-openfeign的Jar包下看到有Ribbon的包,DefaultFeignLoadBalancedConfiguration类的feignClient方法,来构建一个Client客户端,
接着我们看到有LoadBalancerFeignClient的execute方法,FeignLoadBalancer类有一个静态内部类,会构建一个request请求
FeignLoadBalancer继承了AbstractLoadBalancerAwareClient抽象类
底层AbstractLoadBalancerAwareClient的executeWithLoadBalancer方法真正构建了一个http请求。
看到这个方法相信大家对里面的参数都不陌生,有涉及到服务端的host、port,显然是为了拼接需要访问服务端的URI
最后通过调IClient接口执行execute请求服务端,我们看到这个接口的实现有很多。
我引入的是ribbon-httpclient:2.3.0,可以看到有两个请求类已经被禁止,原因无非就是效率太低(猜的…)
目前使用比较多的是OkHttp以及效率更高的OkHttp3,OkHttp3该框架能够高效率的允许连接到同一个主机地址的所有请求,同时还能够缓存响应数据来减少重复的网络请求 以及数据流量的消耗… 这个后面有空会出个OkHttp3的文章。
总结
这里我们对Feign的调用原理通过追踪代码,做了一个简单的分析,其实Feign远不止这些,它还有很多强大的功能,以及提到的Ribbon,作为客户端的负载均衡也是拥有强大的功能,后面会经过学习以及对框架底层的深究继续通过写文章,帮助大家一起学习。如果有分析不对的地方,希望小伙伴们及时提出错误🙏