一、Feign介绍

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

Spring Cloud Alibaba架构 spring cloud alibaba feign_open feign

二、OpenFeign使用

项目目录结构:

Spring Cloud Alibaba架构 spring cloud alibaba feign_spring_02

1.引入依赖

Spring Cloud Alibaba架构 spring cloud alibaba feign_拦截器_03

spring cloud alibaba 2021取消了Ribbon功能,此时需要添加loadbalancer依赖,否则会报以下错误

Spring Cloud Alibaba架构 spring cloud alibaba feign_open feign_04

2.编程调用接口+@FeignClient注解

Spring Cloud Alibaba架构 spring cloud alibaba feign_拦截器_05

3.开启使用 (在调用端启动类上添加@EnableFeignClients注解)

Spring Cloud Alibaba架构 spring cloud alibaba feign_spring cloud_06

4.发起调用

Spring Cloud Alibaba架构 spring cloud alibaba feign_spring_07


Spring Cloud Alibaba架构 spring cloud alibaba feign_拦截器_08

三、日志配置

在遇到接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置Feign的日志了,以此让Feign把请求信息输出出来。

1. 定义一个配置类,指定日志级别

Spring Cloud Alibaba架构 spring cloud alibaba feign_拦截器_09


通过源码可以看到日志等级有4种,分别是:

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

Spring Cloud Alibaba架构 spring cloud alibaba feign_Cloud_10

2.局部配置,让调用的微服务生效,在@FeignClient注解中指定使用的配置类

Spring Cloud Alibaba架构 spring cloud alibaba feign_spring_11

3.在yml配置文件中执行Client的日志级别才能正常输出日志,格式是“logging.level.feign接口包路径=debug”

# SpringBoot默认的日志级别是info,因此feign的debug日志级别默认不会输出
logging:
  level:
    top.xinchilde.nacos_client_feign.feign: debug

4. 调用接口查看日志信息

Spring Cloud Alibaba架构 spring cloud alibaba feign_spring cloud_12

5.补充:局部配置可以在yml中配置

对于属性配置类:org.springframework.cloud.openfeign.FeignClientProperties.FeignClientConfiguration

feign:
  client:
    config:
      service-client1: # 对应服务名
        loggerLevel: BASIC

Spring Cloud Alibaba架构 spring cloud alibaba feign_拦截器_13

四、契约配置

作用场景:用于使用原生Feign的代码升级新版Spring Cloud,不改变旧有Feign原生写法的代码使用。

Spring Cloud在Feign的基础上做了拓展,使用spring MVC的注解来完成Feign的功能。原生的Feign是不支持Spring MVC注解的,如果你在想Spring Cloud中使用原生的注解方式来定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud中默认的是SpringMvcContract。
Spring Cloud 1早期版本就使用的原生Feign,随着netflix的停更替换成了Open Feign

1. 修改契约配置,支持Feign原生的注解

Spring Cloud Alibaba架构 spring cloud alibaba feign_open feign_14


关于SpringMvcContract

Spring Cloud Alibaba架构 spring cloud alibaba feign_拦截器_15

@Bean
    public Contract feignContract() {
        return new SpringMvcContract();
    }

2. FeignService中配置使用Feign原生注解

Spring Cloud Alibaba架构 spring cloud alibaba feign_Cloud_16


Spring Cloud Alibaba架构 spring cloud alibaba feign_open feign_17

3. 补充,也可以通过yml配置契约配置

feign:
  client:
    config:
      service-client1: # 对应服务名
        loggerLevel: BASIC
        contract: feign.Contract.Default #指定Feign原生注解契约配置

Spring Cloud Alibaba架构 spring cloud alibaba feign_拦截器_18

五、超时时间配置

通过Options可以配置连接超时时间和读取超时时间,Options的第一个参数是链接超时时间(ms),默认值是10s;第二个是请求超时时间(ms),默认值是60s;

Spring Cloud Alibaba架构 spring cloud alibaba feign_spring_19

1. 全局配置

// import feign.Request;
    @Bean
    public Request.Options options(){
    	// Request.Options(int connectTimeoutMillis, int readTimeoutMillis)方法已经过时
        return new Request.Options(10000,60000);
    }

2. yml配置

feign:
  client:
    config:
      service-client1: # 对应服务名
        # 连接超时时间
        connectTimeout: 10000
        # 请求处理超时时间
        readTimeout: 60000

六、自定义拦截器

1.介绍

OpenFeign组件中有这么一个接口——RequestInterceptor 。我们来看一下源码中关于这个接口的介绍。

package feign;
 
/**
 * 可以配置零个或多个请求拦截器,可以用于例如给所有请求添加请求头信息.但是不能保证拦截器的应用顺 
 * 序。一旦拦截器被应用,就会调用Target类中的apply(RequestTemplate)方法去创建不可变的http请 
 * 求,该请求通过Client类中的execute(Request, feign.Request.Options)发送。
 *
 * 拦截器是在设置rest模板参数后才被应用的,因此不能再拦截器中添加参数,比如不能再    
 * apply(RequestTemplate)方法中给/path/{foo}/bar中的foo设置参数。
 * 这个类类似于RequestInterceptor.intercept()方法,可以实现读取、删除或以其他方式改变请求模板 
 * 的任何部分。
 */
public interface RequestInterceptor {
 
  /**
   * 可以被每个请求调用。使用RequestTemplate提供的这个方法可以添加数据。
   */
  void apply(RequestTemplate template);
}

2. 代码配置

Spring Cloud Alibaba架构 spring cloud alibaba feign_spring_20

3.yml配置

feign:
  client:
    config:
      service-client1: # 对应服务名
      	
        loggerLevel: FULL # 我添加的信息在header,所以只有HEADERS、和FULL级别才能展示
        requestINterceptors[0]: # 配置拦截器
       	# 自定义拦截器,此时CustomFeignInterceptor类不需要添加@Component注解
          top.xinchilde.nacos_client_feign.interceptor.CustomFeignInterceptor

3.调用结果

Spring Cloud Alibaba架构 spring cloud alibaba feign_拦截器_21