计算机系统应用教程网站

网站首页 > 技术文章 正文

实战Spring Cloud Feign 高级篇,请求压缩,提升性能

btikc 2024-09-10 12:02:17 技术文章 35 ℃ 0 评论

1、简介

Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。SpringCloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。

1)Feign可帮助我们更加便捷,优雅地调用HTTP API。

2)在SpringCloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。

3)Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。

4)SpringCloud对Feign进行了增强,使Feign支持了SpringMVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。

2、实例

2.1 Feign的配置

从Spring Cloud Edgware开始,Feign支持使用属性自定义Feign。对于一个指定名称的FeignClient(例如该Feign Client的名称为 feignName ),Feign支持如下配置项:

2.2 请求压缩

Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数即可开启请求与响应的压缩功能:

同时,我们也可以对请求的数据类型,以及触发压缩的大小下限进行设置:

注:上面的数据类型、压缩大小下限均为默认值

2.3 日志级别

在开发或者运行阶段往往希望看到Feign请求过程的日志记录,默认情况下Feign的日志是没有开启的。要想用属性配置方式来达到日志效果,只需在 application.yml 中添加如下内容即可:

logging.level.xx : debug : Feign日志只会对日志级别为debug的做出响应

feign.client.config.shop-service-product.loggerLevel : 配置Feign的日志Feign有四种日志级别:1)NONE【性能最佳,适用于生产】:不记录任何日志(默认值)

2)BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间

3)HEADERS:记录BASIC级别的基础上,记录请求和响应的header。

4)FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。

2.4 源码分析

通过上面的使用过程,@EnableFeignClients和@FeignClient两个注解就实现了Feign的功能,那我们从@EnableFeignClients注解开始分析Feign的源码(1)EnableFeignClients注解

通过 @EnableFeignClients 引入了FeignClientsRegistrar客户端注册类

(2)FeignClientsRegistrar注册类

通过其类结构可知,由于实现了ImportBeanDefinitionRegistrar接口,那么在registerBeanDefinitions()中就会解析和注册BeanDefinition,主要注册的对象类型有两种:

1)注册缺省配置的配置信息

2)注册那些添加了@FeignClient的类或接口 : 这也是我们讨论的重点

该方法主要是扫描类路径,对所有的FeignClient生成对应的 BeanDefinitio 。同时又调用了registerClientConfiguration 注册配置的方法,这里是第二处调用。这里主要是将扫描的目录下,每个项目的配置类加载的容器当中。调用 registerFeignClient 注册对象

(3) 注册FeignClient对象

通过分析可知:我们最终是向Spring中注册了一个bean,bean的名称就是类或接口的名称(也就是本例中的FeignService),bean的实现类是FeignClientFactoryBean,其属性设置就是我们在@FeignClient中定义的属性。那么下面我们在Controller中对FeignService的的引入,实际就是引入了FeignClientFactoryBean 类

(4) FeignClientFactoryBean类对@EnableFeignClients注解的源码进行了分析,了解到其主要作用就是把带有@FeignClient注解的类或接口用FeignClientFactoryBean类注册到Spring中。

通过 FeignClientFactoryBean 类结构可以发现其实现了FactoryBean类,那么当从ApplicationContext中获取该bean的时候,实际调用的是其getObject()方法。返回调用getTarget()方法

1)FeignClientFactoryBean实现了FactoryBean的getObject、getObjectType、isSingleton方法;实现了InitializingBean的afterPropertiesSet方法;实现了ApplicationContextAware的setApplicationContext方法

2)getObject调用的是getTarget方法,它从applicationContext取出FeignContext,然后构造Feign.Builder并设置了logger、encoder、decoder、contract,之后通过configureFeign根据FeignClientProperties来进一步配置Feign.Builder的retryer、errorDecoder、request.Options、requestInterceptors、queryMapEncoder、decode404

3)初步配置完Feign.Builder之后再判断是否需要loadBalance,如果需要则通过loadBalance方法来设置,不需要则在Client是LoadBalancerFeignClient的时候进行unwrap

(5) 发送请求由上可知,FeignClientFactoryBean.getObject()具体返回的是一个代理类,具体为FeignInvocationHandler

  • FeignInvocationHandler实现了InvocationHandler,是动态代理的代理类。
  • 当执行非Object方法时进入到this.dispatch.get(method)).invoke(args)
  • dispatch是一个map集合,根据方法名称获取MethodHandler。具体实现类为

SynchronousMethodHandler

  • SynchronousMethodHandler内部创建了一个RequestTemplate对象,是Feign中的请求模板对象。内部封装了一次请求的所有元数据。
  • retryer中定义了用户的重试策略。
  • 调用executeAndDecode方法通过client完成请求处理,client的实现类是LoadBalancerFeignClient

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表