• 官方文档
  • 中文文档

    1. 简介

    Feign 是一个声明式 WebService 客户端。使用 Feign 能让编写 Web Service 客户端更加简单。它的使用方法是定义一个服务接口然后在上面添加注解。Feign 也支持可拔插式的编码器和解码器。Spring Cloud 对 Feign 进行了封装,使其支持了 Spring MVC 标准注解和 HttpMessageConverters 。Feign 可以与 Eureka 和 Ribbon 组合使用以支持负载均衡。
    在使用 Ribbon + RestTemplate 时,利用 RestTemplate 对 http 请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign 在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在 Feign 的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用 Spring Cloud Ribbon 时,自动封装服务调用客户端的开发量。
    Feign 集成了 Ribbon,利用 Ribbon 维护了 Payment 的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与 Ribbon 不同的是,通过 Feign 只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。Feign 天生就带有负载均衡机制
    image.png

    2. 使用

    2.1 模块搭建

    2.1.1 引入依赖

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <parent>
    6. <artifactId>cloud2020</artifactId>
    7. <groupId>com.example.com.springcloud</groupId>
    8. <version>1.0-SNAPSHOT</version>
    9. </parent>
    10. <modelVersion>4.0.0</modelVersion>
    11. <artifactId>order-feign</artifactId>
    12. <properties>
    13. <maven.compiler.source>16</maven.compiler.source>
    14. <maven.compiler.target>16</maven.compiler.target>
    15. </properties>
    16. <dependencies>
    17. <!--openfeign-->
    18. <dependency>
    19. <groupId>org.springframework.cloud</groupId>
    20. <artifactId>spring-cloud-starter-openfeign</artifactId>
    21. </dependency>
    22. <!--eureka client-->
    23. <dependency>
    24. <groupId>org.springframework.cloud</groupId>
    25. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    26. </dependency>
    27. <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
    28. <dependency>
    29. <groupId>com.example.com.springcloud</groupId>
    30. <artifactId>common</artifactId>
    31. <version>1.0-SNAPSHOT</version>
    32. </dependency>
    33. <!--web-->
    34. <dependency>
    35. <groupId>org.springframework.boot</groupId>
    36. <artifactId>spring-boot-starter-web</artifactId>
    37. </dependency>
    38. <dependency>
    39. <groupId>org.springframework.boot</groupId>
    40. <artifactId>spring-boot-starter-actuator</artifactId>
    41. </dependency>
    42. <!--一般基础通用配置-->
    43. <dependency>
    44. <groupId>org.springframework.boot</groupId>
    45. <artifactId>spring-boot-devtools</artifactId>
    46. <scope>runtime</scope>
    47. <optional>true</optional>
    48. </dependency>
    49. <dependency>
    50. <groupId>org.projectlombok</groupId>
    51. <artifactId>lombok</artifactId>
    52. <optional>true</optional>
    53. </dependency>
    54. <dependency>
    55. <groupId>org.springframework.boot</groupId>
    56. <artifactId>spring-boot-starter-test</artifactId>
    57. <scope>test</scope>
    58. </dependency>
    59. </dependencies>
    60. </project>

    2.1.2 配置文件

    ```properties server: port: 80

eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka register-with-eureka: false

  1. <a name="UHRWf"></a>
  2. ### 2.1.3 主启动类
  3. ```java
  4. package com.example.springcloud;
  5. import org.springframework.boot.SpringApplication;
  6. import org.springframework.boot.autoconfigure.SpringBootApplication;
  7. import org.springframework.cloud.openfeign.EnableFeignClients;
  8. @SpringBootApplication
  9. @EnableFeignClients
  10. public class OrderFeignApplication {
  11. public static void main(String[] args) {
  12. SpringApplication.run(OrderFeignApplication.class, args);
  13. }
  14. }

2.1.4 业务类

新建接口并且用注解标注:

  1. package com.example.springcloud.service;
  2. import com.example.springcloud.common.CommonResults;
  3. import com.example.springcloud.domain.Payment;
  4. import org.springframework.cloud.openfeign.FeignClient;
  5. import org.springframework.stereotype.Service;
  6. import org.springframework.web.bind.annotation.PostMapping;
  7. import org.springframework.web.bind.annotation.RequestBody;
  8. @Service
  9. @FeignClient(value = "cloud-payment-service")
  10. public interface PaymentFeignService {
  11. @PostMapping("/create")
  12. CommonResults create(@RequestBody Payment payment);
  13. }

然后可以在 controller 中调用。

  1. package com.example.springcloud.controller;
  2. import com.example.springcloud.service.PaymentFeignService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.RestController;
  5. @RestController
  6. public class OrderFeignController {
  7. @Autowired
  8. private PaymentFeignService paymentFeignService;
  9. }

2.2 OpenFeign 超时控制

OpenFeign 默认等待时间是1秒钟,超时即报错。如果服务提供方因为某种原因出现网络延迟,超时时间超过1秒钟,那么在用 OpenFeign 调用服务的时候就会出现超时报错。
可以在配置文件中配置超时时间。

  1. #设置feign客户端超时时间(OpenFeign默认支持ribbon)
  2. ribbon:
  3. #指的是建立连接后从服务器读取到可用资源所用的时间
  4. ReadTimeout: 5000
  5. #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  6. ConnectTimeout: 5000

2.3 日志打印

Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节。

2.3.1 日志级别

  1. NONE:默认的,不显示任何日志;
  2. BASIC:仅记录请求方法、URL、响应状态码及执行时间;
  3. HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
  4. FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。

    2.3.2 使用

  5. 编写配置类 ```java package com.example.springcloud.config;

import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;

@Configuration public class FeignConfig { @Bean Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; } }

  1. 2. 配置文件
  2. ```properties
  3. logging:
  4. level:
  5. #feign日志以什么级别监控哪个接口
  6. com.jg.springcloud.service.PaymentFeignService: debug