spring cloud openfeign 详解

483 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

Openfeign 用于远程调用,配合服务注册中心使用

在项目中使用openfeign

添加依赖

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

添加后会默认导入Ribbon依赖包。
OF支持spring-cloud-starter-loadbalancer组件,如果要改为使用Loadbalancer,则需要添加这个依赖。

项目中启用OF

在启用类或者配置类上,添加注解:

@EnableFeignClients
@SpringBootApplication
public class DemoCloudUserApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoCloudUserApplication.class, args);
    }
}

启用OpenFeign后,会自动扫面@FeignClient注解(见下文),生成远程服务接口的代理。

定义远程接口

在项目中,需要定义和远程客户端服务接口相同的签名接口。

@FeignClient("demo-cloud-order")
public interface OrderApi {

    @GetMapping("getByUserId")
    public List<OrderEntity> get(@RequestParam("userId") String userId);
}

  • @FeignClient(value="")中value指明该接口对照的远程被调用接口所属服务名(在注册中心中的名字,一般是被调用服务的spring.application.name)
  • GetMapping中的ServiceID必须和远程被调用接口一致,但是接口名get可以随便写。
  • 如果需要参数userId,必须采用@RequestParam注解,否则会默认成Post请求,导致失败。

定义后,在项目中像正常使用本地接口一样使用即可。

配置

通过配置类配置

FeignClient默认采用FeignClientsConfiguration配置,如果需要自定义配置,可以使用:

@FeignClient(name = "stores", configuration = FooConfiguration.class)

这样FooConfiguration中定义的配置项会覆盖默认FeignClientsConfiguration中的配置。

FooConfiguration.class定义不需要添加@Configuration或者@Component注解,否则会变成默认的配置。

// @Configuration
public class FooConfiguration {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("user", "password");
    }
}

通过配置文件配置

FeignClient可以通过配置文件进行配置:

  • 这里指的注册中心的被调用的远程服务名,如demo-cloud-order
  • 如果需要对全部远程调用都启用配置,feignName可以设置为default即可
feign:
    client:
        config:
            <feignName>: 
                connectTimeout: 5000
                readTimeout: 5000
                loggerLevel: full
                errorDecoder: com.example.SimpleErrorDecoder
                retryer: com.example.SimpleRetryer
                defaultQueryParameters:
                    query: queryValue
                defaultRequestHeaders:
                    header: headerValue
                requestInterceptors:
                    - com.example.FooRequestInterceptor
                    - com.example.BarRequestInterceptor
                decode404: false
                encoder: com.example.SimpleEncoder
                decoder: com.example.SimpleDecoder
                contract: com.example.SimpleContract
                capabilities:
                    - com.example.FooCapability
                    - com.example.BarCapability
                queryMapEncoder: com.example.SimpleQueryMapEncoder
                metrics.enabled: false

如果配置文件和配置类同时存在,配置文件级别高。
可以使用 feign.client.default-to-properties=false 设置配置类高于配置文件

超时配置

有两类配置:

  • connectTimeout:防止服务连接时间太长,导致调用端一直阻塞
  • readTimeout:每次发起请求,防止从连接开始到响应时间太长,导致调用端一直阻塞

继承的支持

可以把remote服务接口抽象出来单独的API接口,调用方可以直接引用该接口文件,并直接继承,但要对API接口进行统一的版本管理,防止更新后导致调用失败。

// 公共接口
public interface OrderApi {
    @GetMapping("list")
    public String list(@RequestParam("userId") String userId);
}
// 服务实现
@RestController
public class OrderController implements OrderApi {

    @Override
    public String list(String userId){
        return userId+":order-list";
    }
}
//远程调用
@FeignClient("demo-cloud-order")
public interface OrderClient extends OrderApi {

}

请求/响应启用压缩功能

# 响应
feign.compression.response.enabled=true
# 请求
feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

日志功能

全局配置

1.添加配置类,指定日志类型

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLeave(){
        // Bacis:包括请求的方法,请求的URL和响应时间
        // FULL:请求+请求body+响应
        // HEADERS:请求头+基本请求信息
        // NONE:不记录(默认)
        return Logger.Level.FULL;
    }
}

2.修改springboot的日志级别为debug

第一步中修改了openfeign的日志级别是 debug,但是springboot默认日志级别是Info,debug<info,所以需要也改为debug,openfeign的日志才会生效

logging:
	level:
  	com.base.service: debug # 这里是openfeign client 所在的包路径

局部配置

1.配置类,指定日志类型

// @Configuration 不需要注解
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLeave(){
        // Bacis:包括请求的方法,请求的URL和响应时间
        // FULL:请求+请求body+响应
        // HEADERS:请求头+基本请求信息
        // NONE:不记录(默认)
        return Logger.Level.FULL;
    }
}

针对特定的openfeign client 激活配置:

@FeignClient("demo-cloud-order",configuration=FeignConfig.class)
public interface OrderClient extends OrderApi {

}

2.修改配置文件,配置服务的打印级别

feign:
	client:
  	config:
    	demo-cloud-order:
      	loggerlevel: FULL

使用缓存

相同的响应可以使用缓存。