1. 概述
Feign 是一个声明式 WebService 客户端。使用 Feign 能让编写 Web Service 客户端更加简单。它的使用方法时定义一个服务接口然后在上面添加注解(Feign 在消费端使用)。Feign 也支持可插拔式的编码器和解码器。Spring Cloud 对 Feign 进行了封装,使其支持了 SpringMVC 标准注解和 HttpMessageConverters。Feign 可以与 Enreka 和 Ribbon 组合使用以支持负载均衡。
2. 基本使用
- 8080 消费端服务引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
- 8080 消费端服务主启动类上新增注解:
@EnableFeignClients
- 8080 消费端服务新增 8001/8002 服务 Controller 对应的接口 PaymentFeignService
@Component @FeignClient(value = "CLOUD-PAYMENT-SERVICE") public interface PaymentFeignService { /** * 查询 payment * @param id * @return */ @GetMapping("/payment/{id}") CommonResult<Payment> getPaymentById(@PathVariable("id") Long id); }
- 测试 http://localhost:8080/order/payment/1,Feign 自带负载均衡配置项
3. 超时控制
- 8001/8002 服务 Controller 新增个测试接口
@GetMapping("/feign/timeout") public String testFeignTimeout() { try { Thread.sleep(3000); } catch (InterruptedException e) { log.error("timeout throw Ex: {}", e); } return port; }
- 8080 消费端服务在 PaymentFeignService 新增对应抽象方法
@GetMapping("/feign/timeout") public String testTimeout() { // FeignClient default wait 1 second ... return paymentFeignService.testFeignTimeout(); }
- 测试上述接口会抛出异常:feign.RetryableException: Read timed out executing GET http://CLOUD-PAYMENT-SERVICE/payment/feign/timeout
- 修复:YML 文件里需要开启 OpenFeign 客户端的超时控制
# 设置 Feign 客户端超时时间 (OpenFeign 默认支持 Ribbon) ribbon: # 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间 ReadTimeout: 5000 # 指的是建立连接后从服务器读取到可用资源所用的时间 ConnectTimeout: 5000
- 然后再测,ok 了
4. 日志打印
Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节。说白了就是对 Feign 接口的调用情况进行监控和输入。
日志级别:
- NONE:默认的,不显示任何日志;
- BASIC:仅记录请求方法、URL、响应状态码及执行时间;
- HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息;
- FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。
- 配置日志 Bean
@Configuration public class FeignConfig { @Bean Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; } }
- YML 文件里需要开启日志的 Feign 客户端
# 以指定日志级别监控指定请求接口 logging: level: cn.edu.nuist.cloud.feign.PaymentFeignService: debug
- 发送请求,然后查看控制台
PaymentFeignService : [PaymentFeignService#testFeignTimeout] ---> GET http://CLOUD-PAYMENT-SERVICE/payment/feign/timeout HTTP/1.1 PaymentFeignService : [PaymentFeignService#testFeignTimeout] ---> END HTTP (0-byte body) PaymentFeignService : [PaymentFeignService#testFeignTimeout] <--- HTTP/1.1 200 (3005ms) PaymentFeignService : [PaymentFeignService#testFeignTimeout] connection: keep-alive PaymentFeignService : [PaymentFeignService#testFeignTimeout] content-length: 4 PaymentFeignService : [PaymentFeignService#testFeignTimeout] content-type: text/plain;charset=UTF-8 PaymentFeignService : [PaymentFeignService#testFeignTimeout] date: Sun, 13 Feb 2022 09:45:49 GMT PaymentFeignService : [PaymentFeignService#testFeignTimeout] keep-alive: timeout=60 PaymentFeignService : [PaymentFeignService#testFeignTimeout] PaymentFeignService : [PaymentFeignService#testFeignTimeout] 8001 PaymentFeignService : [PaymentFeignService#testFeignTimeout] <--- END HTTP (4-byte body)