上一节( 跟我学Spring Cloud(Finchley版)-09-Feign )讲了Feign的入门姿势并深入对比了RestTemplate,本节来深入探讨Feign的高级特性。总的来说,Feign是一个相对简单的组件,但细节还是比较多的,一不小心就可能入坑,注意点我会以WARINING的形式标记出来,便于读者查阅。

Feign配置自定义【细粒度配置】

方式一、代码配置方式

Spring Cloud Netflix provides the following beans by default for feign (BeanType beanName: ClassName):

  • Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder)
  • Encoder feignEncoder: SpringEncoder
  • Logger feignLogger: Slf4jLogger
  • Contract feignContract: SpringMvcContract
  • Feign.Builder feignBuilder: HystrixFeign.Builder
  • Client feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient, otherwise the default feign client is used.

The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled orfeign.httpclient.enabled to true, respectively, and having them on the classpath.

Spring Cloud Netflix does not provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client:

  • Logger.Level
  • Retryer
  • ErrorDecoder
  • Request.Options
  • Collection<RequestInterceptor>
  • SetterFactory

代码示例:自定义日志级别

默认Feign是不打印任何日志的,下面我们来开启Feign的日志,Feign有四种日志级别:

  • NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。
  • BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。
  • HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
  • FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。

插科打诨 & 恶意揣测

跟我学Spring Cloud(Finchley版)-09-Feign说过,Feign的性能中等,可能官方对自己的性能也是知道的,索性全部关闭日志了,哈哈

  • 将前文的Feign Client修改为如下:

    @FeignClient(name = "microservice-provider-user", configuration = UserFeignConfig.class)
    public interface UserFeignClient {
    @GetMapping("/users/{id}")
    User findById(@PathVariable("id") Long id);
    }/**
    * 该Feign Client的配置类,注意:
    * 1. 该类可以独立出去;
    * 2. 该类上也可添加@Configuration声明是一个配置类;
    * 配置类上也可添加@Configuration注解,声明这是一个配置类;
    * 但此时千万别将该放置在主应用程序上下文@ComponentScan所扫描的包中,
    * 否则,该配置将会被所有Feign Client共享,无法实现细粒度配置!
    * 个人建议:像我一样,不加@Configuration注解
    *
    * @author zhouli
    */
    class UserFeignConfig {
    @Bean
    public Logger.Level logger() {return Logger.Level.FULL;
    }
    }

    如代码所示,使用注解@FeignClientconfiguration 属性,指定一个类,即可实现Feign配置自定义。

    TIPS

    • 本例简单起见,直接弄了个外部类作为配置类UserFeignConfig,读者也可将该类独立出去作为一个public class

    WARNING

    • 配置类上也可添加@Configuraiton 注解,声明这是一个配置类;但此时千万别将该放置在主应用程序上下文@ComponentScan 所扫描的包中,否则,该配置将会被所有Feign Client共享(相当于变成了通用配置,其实本质还是Spring父子上下文扫描包重叠导致的问题),无法实现细粒度配置!
    • 个人建议:像我一样,不加@Configuration注解,省得进坑。

    联想记忆

    还记得Ribbon如何使用Java代码自定义配置吗?Ribbon使用Java代码自定义配置时也必须防止配置类在@ComponentScan 上下文内,详见: 跟我学Spring Cloud(Finchley版)-08-Ribbon深入

  • application.yml 中添加以下内容,将该Feign接口的日志级别设置为DEBUG:

    logging:
    level:com.itmuch.cloud.study.user.feign.UserFeignClient: debug
  • 此时,当该Feign Client的方法被调用时,将会打印类似如下的日志:

    2019-01-10 22:14:10.611 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById] ---> GET http://microservice-provider-user/users/1 HTTP/1.1
    2019-01-10 22:14:10.611 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById] ---> END HTTP (0-byte body)
    2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById] <--- HTTP/1.1 200 (11ms)
    2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById] content-type: application/json;charset=UTF-8
    2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById] date: Thu, 10 Jan 2019 14:14:10 GMT
    2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById] transfer-encoding: chunked
    2019-01-10 22:14:10.623 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById]
    2019-01-10 22:14:10.624 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById] {"id":1,"username":"account1","name":"张三","age":20,"balance":100.00}
    2019-01-10 22:14:10.624 DEBUG 26321 --- [nio-8010-exec-2] c.i.c.study.user.feign.UserFeignClient   : [UserFeignClient#findById] <--- END HTTP (72-byte body)

配套代码

GitHub: https://github.com/eacdy/spring-cloud-study/tree/master/2018-Finchley/microservice-consumer-movie-feign-config-java

Gitee: https://gitee.com/itmuch/spring-cloud-study/tree/master/2018-Finchley/microservice-consumer-movie-feign-config-java

方法二、属性配置方式【Edgware开始提供】

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

feign:client:config:feignName:connectTimeout: 5000  # 相当于Request.OptionsreadTimeout: 5000     # 相当于Request.Options# 配置Feign的日志级别,相当于代码配置方式中的LoggerloggerLevel: full# Feign的错误×××,相当于代码配置方式中的ErrorDecodererrorDecoder: com.example.SimpleErrorDecoder# 配置重试,相当于代码配置方式中的Retryerretryer: com.example.SimpleRetryer# 配置拦截器,相当于代码配置方式中的RequestInterceptorrequestInterceptors:- com.example.FooRequestInterceptor- com.example.BarRequestInterceptordecode404: false

TIPS

个人并不建议配置retryer,Spring Cloud Camden以及之后的版本中,Spring Cloud关闭了Feign的重试,而是使用Ribbon的重试。如果自己再定义Feign的重试后,那么可能会造成重试特性的混乱。笔者已在<https://github.com/spring-cloud/spring-cloud-netflix/issues/2330&gt; 提出该问题。

代码示例:自定义日志级别

要想用属性配置方式来达到上面Java代码方式的效果,只需在application.yml 中添加如下内容即可:

feign:client:config:microservice-provider-user:loggerLevel: full
logging:level:com.itmuch.cloud.study.user.feign.UserFeignClient: debug

配套代码

GitHub:<https://github.com/eacdy/spring-cloud-study/tree/master/2018-Finchley/microservice-consumer-movie-feign-config-properties&gt;

Gitee:<https://gitee.com/itmuch/spring-cloud-study/tree/master/2018-Finchley/microservice-consumer-movie-feign-config-properties&gt;

Feign配置自定义【通用配置】

上面讨论了如何配置特定名称的Feign Client,那么如果想为所有的Feign Client都进行配置,该怎么办呢?我们知道,@EnableFeignClients 注解上有个defaultConfiguration 属性,我们可以将默认配置写成一个类,然后用defaultConfiguration 来引用,例如:

@EnableFeignClients(defaultConfiguration = DefaultRibbonConfig.class)

如果想使用配置属性的方式,只需使用类似如下的写法即可。

feign:client:config:default:connectTimeout: 5000readTimeout: 5000loggerLevel: basic

配置优先级

如果你不小心又使用了Java代码配置Feign,同时又使用了配置属性配置Feign,那么使用配置属性的优先级更高。配置属性配置的方式将会覆盖Java代码配置。如果你想修改代码配置方式的优先级,可使用如下属性:feign.client.default-to-properties=false

压缩

一些场景下,我们可能需要对请求或响应进行压缩,此时可使用以下属性启用Feign的压缩功能。

feign.compression.request.enabled=true
feign.compression.response.enabled=true

对于请求的压缩,Feign还提供了更为详细的设置,例如:

feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

其中,feign.compression.request.mime-types 用于支持的媒体类型列表,默认是text/xml、application/xml以及application/json。

feign.compression.request.min-request-size 用于设置请求的最小阈值,默认是2048。

继承

比较重要,业界对继承特性看法非常不一样,喜欢的特别喜欢,讨厌的特别讨厌(例如我)。将以番外形式体现,并对比两者优缺点,以及最佳实践,明天或后天更新,敬请期待。

其他特性

Feign其他特性我已经写了很多了,知识体系已经完备了。懒得再在这个系列里凑字数,这不是我的风格,直接贴地址吧:

  • 生产技巧:Feign如何控制Hystrix的启停、超时、熔断?
  • 使用Feign实现Form表单提交
  • 如何使用Feign构造多参数的请求
  • Spring Cloud中,Feign常见问题总结
  • Spring Cloud中,如何解决Feign/Ribbon第一次请求失败的问题?
  • 使用Spring Cloud Feign上传文件

本文首发

http://www.itmuch.com/spring-cloud/finchley-10/

干货分享

转载于:https://blog.51cto.com/10180481/2342358

跟我学Spring Cloud(Finchley版)-10-Feign深入相关推荐

  1. Spring Cloud Finchley版中Consul多实例注册的问题处理

    由于Spring Cloud对Etcd的支持一直没能从孵化器中出来,所以目前来说大多用户还在使用Eureka和Consul,之前又因为Eureka 2.0不在开源的消息,外加一些博眼球的标题党媒体使得 ...

  2. hystrix 全局熔断_跟我学Spring Cloud(Finchley版)14Feign使用Hystrix

    Feign默认已经整合了Hystrix,本节详细探讨Feign使用Hystrix的具体细节. 服务降级 1 加配置,默认Feign是不启用Hystrix的,需要添加如下配置启用Hystrix,这样所有 ...

  3. 跟我学Spring Cloud(Finchley版)-07-Ribbon入门

    经过前文讲述,我们已经实现了服务发现.本节来解决 跟我学Spring Cloud(Finchley版)-02-构建分布式应用 提到的如下问题: 负载均衡如何考虑?难道得在电影微服务和用户微服务之间加个 ...

  4. 跟我学Spring Cloud(Finchley版)-04-服务注册与服务发现-原理剖析

    为什么80%的码农都做不了架构师?>>>    第2节( 跟我学Spring Cloud(Finchley版)-02-构建分布式应用 )说过: 地址硬编码问题--电影微服务中将用户微 ...

  5. 告诉老默我想学Spring Cloud了(新手篇):从0到1搭建Spring Cloud项目(实际项目开发的浓缩精华版)

    告诉老默我想学Spring Cloud了(新手篇):从0到1搭建Spring Cloud项目 一.前言 二.如何选择版本 2.1 SpringCloud 和 Spring Boot 版本选型 2.1. ...

  6. Spring Cloud Finchley OpenFeign的重试配置相关的坑

    如题,本文基于Spring Cloud Finchley.SR2 OpenFeign的重试 OpenFeign配置重试后,逻辑分析 对比Daltson和Finchley的基本组件,发现Ribbon还有 ...

  7. 一起来学Spring Cloud | 第五章:熔断器 ( Hystrix)

    在微服务项目中,一个系统可以分割成很多个不同的服务模块,不同模块之间我们通常需要进行相互调用.springcloud中可以使用RestTemplate+Ribbon和Feign来调用(工作中基本都是使 ...

  8. 3.spring cloud + zookeeper注册中心 + Feign调用案例

    3.spring cloud + zookeeper注册中心 + Feign调用案例 3.1.pom.xml定义 <?xml version="1.0" encoding=& ...

  9. 跟我学Spring Cloud(Finchley版)-16-Zuul

    为什么80%的码农都做不了架构师?>>>    至此,已实现基于Eureka的服务发现,基于Ribbon的负载均衡,Feign也为我们提供了很不错的远程调用能力,使用Hystrix后 ...

最新文章

  1. open***无法启动日志报错解决方法
  2. BBC称中国人加班时间远超欧美:工作效率未必高
  3. 如何在设计时公开复合控件内的子控件
  4. 实验5_JPEG解码
  5. PHPCMS的产品筛选功能
  6. @Autowired注解实现原理
  7. r软件说明lib文件未指明_软件说明文件
  8. c++ class struct同名_如何把C++的源代码改写成C代码?而C改C++只需一步!
  9. 前端工程师技能之photoshop巧用系列扩展篇——自动切图
  10. oracle 调用main方法,main方法中调用spring注入bean
  11. MIND多兴趣召回实战(一)
  12. 多路径配置udev_多路径multipath配置,udev绑定
  13. js进阶正则表达式10-分组-多行匹配-正则对象的属性(小括号作用:分组,将小括号里面的东西看成一个整体,因为量词只对前一个字符有效)(多行匹配:m)(属性使用:reg.global)...
  14. 经典调用共享变量wait()方法的实例
  15. ASP.NET对IIS中的虚拟目录进行操作
  16. 工作要求,写了一些没用的设计文档
  17. 思源宋体安装过程记录
  18. 《特征值与特征向量》定义、意义及例子
  19. 手机上怎么照证件照照片?教你两招轻松拍出证件照
  20. matlab将图片旋转的代码_我的MATLAB魔方新玩法:拼出任意图案!

热门文章

  1. Category中实现了原始类实例变量的get方法导致的警告
  2. 嵌入式 Linux进程含义知多少
  3. 3D滚动下拉菜单-简直不要太任性
  4. 关于“INS-40922 Invalid Scan Name – Unresolvable to IP address”
  5. 【OpenCV学习】抠图
  6. asp.net编程:asp.net中如何设置页面的编码
  7. 网站路径及文件路径问题
  8. 记一次OOM问题排查过程
  9. 概念化学习Django
  10. shiro配置参考(一)