环境:SpringBoot2.7.16 + SpringCloud2021.0.7
1. 简介
Feign 是一个声明式网络服务客户端。它让编写网络服务客户端变得更容易。要使用 Feign,需要创建一个接口并对其进行注解。它支持可插拔的注解,包括 Feign 注释和 JAX-RS 注释。Feign 还支持可插拔的编码器和解码器。Spring Cloud 增加了对 Spring MVC 注释和使用 Spring Web 默认使用的 HttpMessageConverters 的支持。Spring Cloud 集成了 Eureka、Spring Cloud CircuitBreaker 和 Spring Cloud LoadBalancer,以便在使用 Feign 时提供负载平衡的 http 客户端。以下是简单配置示例:
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
开启功能
@SpringBootApplication
@EnableFeignClients
public class SpringCloudComprehensiveApplication {
}
Feign接口定义
@FeignClient(
url = "http://localhost:8088/demos",
name = "demoService",
configuration = DemoFeignConfiguration.class,
fallback = DemoFeignFallback.class,
fallbackFactory = DemoFeignFallbackFactory.class,
primary = true
)
public interface DemoFeign {
@GetMapping("/info/{id}")
public Object info(@PathVariable("id") Integer id) ;
@PostMapping("/map")
public Object map(@RequestBody Map<String, Object> params) ;
}
以上是一个比较完整的OpenFeign接口的配置。而在绝大多数的项目中这样配置就能够满足所有的需求了。接下来将会介绍OpenFeign实用但又很少被提及到的一些功能。
2. 高级功能
2.1 Feign指标
如果以下条件全部为真,就会创建并注册 MicrometerCapability Bean,以便您的 Feign 客户端向 Micrometer 发布度量指标:
-
feign-micrometer在类路径中
-
容器中存在MeterRegistry Bean对象
-
feign指标属性设置为true(默认为:true)
1. feign.metrics.enabled=true所有Client都生效。
2. feign.client.config.feignName.metrics.enabled=true单一Client被设置为true。
接下来你就可以通过Prometheus进行查看相关的指标信息了。如果你没有集成Prometheus,那么你也可以通过Actuator进行指标的查看。
通过指标名称查看具体的指标数据
2.2 Feign缓存
如果使用 @EnableCaching 注解,则会创建并注册一个 CachingCapability Bean,以便 Feign 客户端识别其接口上的 @Cache* 注解:
@Cacheable(cacheNames = "infos", key = "#id")
@GetMapping("/info/{id}")
public Object info(@PathVariable("id") Integer id) ;
当你第一次请求该接口时,会向远
spring:
cache:
type: redis
redis:
key-prefix: 'feign:'
time-to-live: 60s
程发送请求,再次访问后直接从缓存中获取数据。如果你需要使用的是基于Redis的缓存管理,那么你是可以配置有效期的。这里默认是基于内存的。
数据都缓存到了Redis中。
2.3 @QueryMap支持
OpenFeign @QueryMap 注解支持将 POJO 用作 GET 参数映射。遗憾的是,默认的 OpenFeign QueryMap 注解与 Spring 不兼容,因为它缺少一个value属性。
Spring Cloud OpenFeign 提供了等价的 @SpringQueryMap 注解,用于将 POJO 或 Map 参数注释为查询参数映射。
简单点说:可以将一个对象中的所有属性值以get的方式拼接到地址栏进行传递。
@GetMapping("/format")
Object format(@SpringQueryMap Params params) ;
Controller接口调用
@GetMapping("/format")
public Object format(Params params) {
return this.demoFeign.format(params) ;
}
参数对象
public class Params {
private Long id ;
private String name ;
}
Feign请求日志
: [DemoFeign#format] ---> GET http://localhost:8088/demos/format?name=test&id=111 HTTP/1.1
: [DemoFeign#format] Accept-Encoding: gzip
: [DemoFeign#format] Accept-Encoding: deflate
: [DemoFeign#format] X-API-TOKEN: 666666
将对象中的属性值自动的拼到了地址栏上。
2.4 @MatrixVariable支持
Spring Cloud OpenFeign 支持 Spring @MatrixVariable 注解。如果方法参数传递的是映射,则 @MatrixVariable 路径段是通过用 = 连接映射中的键值对创建的。如果传递的是不同的对象,则使用 = 将 @MatrixVariable 注解(如果已定义)中提供的名称或注解的变量名称与提供的方法参数连接起来。
@GetMapping("/m3/{params}")
public Object matrix3(@MatrixVariable Map<String, List<String>> params) ;
注意:这里需要路径占位符的名称与@MatrixVariable注解的变量名一致。
2.5 @CollectionFormat支持
提供@CollectionFormat注解来支持 feign.CollectionFormat。可以通过传递所需的 feign.CollectionFormat 作为注解值,为 Feign 客户端方法(或整个类的所有方法)添加注解。
@GetMapping("/cf")
@CollectionFormat(feign.CollectionFormat.CSV)
public Object cf(@RequestParam("ids") List<String> ids) ;
调用
this.demoFeign.cf(List.of("S1", "S2", "S3")) ;
请求
: [DemoFeign#cf] ---> GET http://localhost:8088/demos/cf?ids=S1,S2,S3 HTTP/1.1
: [DemoFeign#cf] Accept-Encoding: gzip
: [DemoFeign#cf] Accept-Encoding: deflate
: [DemoFeign#cf] X-API-TOKEN: 666666
: [DemoFeign#cf] ---> END HTTP (0-byte body)
: [DemoFeign#cf] <--- HTTP/1.1 200 (33ms)
参数被自动的编码为:S1,S2,S3。
改为如下设置后
@CollectionFormat(feign.CollectionFormat.PIPES)
参数被自动的编码为:S1|S2|S3。