OpenFeign简介
OpenFeign 全称 Spring Cloud OpenFeign, Spring 官方推出的一种声明式服务调用与负载均衡组件,它的出现就是为了替代进入停更维护状态的 Feign。 OpenFeign 是 Spring Cloud 对 Feign 的二次封装,它具有 Feign 的所有功能,并在 Feign 的基础上增加了对 Spring MVC 注解的支持,例如 @RequestMapping、@GetMapping 和 @PostMapping 等。 OpenFeign 常用注解| 注解 | 说明 |
|---|---|
| @FeignClient | 该注解用于通知 OpenFeign 组件对 @RequestMapping 注解下的接口进行解析,并通过动态代理的方式产生实现类,实现负载均衡和服务调用。 |
| @EnableFeignClients | 该注解用于开启 OpenFeign 功能,当 Spring Cloud 应用启动时,OpenFeign 会扫描标有 @FeignClient 注解的接口,生成代理并注册到 Spring 容器中。 |
| @RequestMapping | Spring MVC 注解,在 Spring MVC 中使用该注解映射请求,通过它来指定控制器(Controller)可以处理哪些 URL 请求,相当于 Servlet 中 web.xml 的配置。 |
| @GetMapping | Spring MVC 注解,用来映射 GET 请求,它是一个组合注解,相当于 @RequestMapping(method = RequestMethod.GET) 。 |
| @PostMapping | Spring MVC 注解,用来映射 POST 请求,它是一个组合注解,相当于 @RequestMapping(method = RequestMethod.POST) 。 |
- Feign 和 OpenFeign 都是 Spring Cloud 下的远程调用和负载均衡组件。
- Feign 和 OpenFeign 作用一样,都可以实现服务的远程调用和负载均衡。
- Feign 和 OpenFeign 都对 Ribbon 进行了集成,都利用 Ribbon 维护了可用服务清单,并通过 Ribbon 实现了客户端的负载均衡。
- Feign 和 OpenFeign 都是在服务消费者(客户端)定义服务绑定接口并通过注解的方式进行配置,以实现远程服务的调用。
- Feign 和 OpenFeign 的依赖项不同,Feign 的依赖为 spring-cloud-starter-feign,而 OpenFeign 的依赖为 spring-cloud-starter-openfeign。
- Feign 和 OpenFeign 支持的注解不同,Feign 支持 Feign 注解和 JAX-RS 注解,但不支持 Spring MVC 注解;OpenFeign 除了支持 Feign 注解和 JAX-RS 注解外,还支持 Spring MVC 注解。
- 首先创建一个
<font style="color:rgb(68, 68, 68);">OpenFeign</font>模块spring-cloud-openfeign-consumer-9006(消费者)

- pom依赖引入
<!--添加 OpenFeign 依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
- 类路径(即 /resources 目录)下,添加一个
<font style="color:rgb(68, 68, 68);">application.yml</font>,配置内容如下
server:port: 9006spring:application:name: spring-cloud-openfeign-consumer-9006eureka:client:#表示是否将自己注册进 EurekaServer默认为true。register-with-eureka: true#是否从 EurekaServer 抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡fetchRegistry: trueservice-url:defaultZone: http://127.0.0.1:9001/eureka
- 在启动类同路径下创建
service包,然后在里面创建一个名为BookService的接口,并在该接口上使用**<font style="color:#E8323C;">@FeignClient </font>**注解实现对服务接口的绑定,代码如下
在编写服务绑定接口时,需要注意以下 2 点:
//添加为容器内的一个组件@Component@FeignClient(value = "SPRING-CLOUD-EUREKA-PROVIDER-BOOK-9002")public interface BookService {//对应服务提供者(8002、9002)Controller 中定义的方法@RequestMapping(value = "/book/get/{id}", method = RequestMethod.GET)public Book get(@PathVariable("id") int id);@RequestMapping(value = "/book/list", method = RequestMethod.GET)public List<Book> selectAll();}
- 在 @FeignClient 注解中,value 属性的取值为:服务提供者的服务名,即服务提供者配置文件(application.yml)中 spring.application.name 的取值。
- 接口中定义的每个方法都与服务提供者(即
spring-cloud-eureka-provider-book-8002、spring-cloud-eureka-provider-book-9002(还是复用前面所学的集群哦))中 Controller 定义的服务方法对应。
- 创建Controller类
@RestController@Slf4jpublic class BookController {@Autowiredprivate BookService bookService; //这里直接使用openfigen绑定的服务进行请求@GetMapping(value = "/book/get/{id}")public Book get(@PathVariable("id") int id) {return bookService.get(id);}@GetMapping(value = "/book/list")public List<Book> list() {return bookService.selectAll();}}
- 主启动类添加 @EnableFeignClients 注解开启 OpenFeign 功能
@SpringBootApplication@EnableFeignClientspublic class SpringCloudOpenfeignConsumer9006Application {public static void main(String[] args) {SpringApplication.run(SpringCloudOpenfeignConsumer9006Application.class, args);}}
Spring Cloud 应用在启动时,OpenFeign 会扫描标有 @FeignClient 注解的接口生成代理,并注人到 Spring 容器中。
- 依次启动服务注册中心集群、服务提供者以及
spring-cloud-openfeign-consumer-9006,启动完访问 http://127.0.0.1:9004/book/get/1 结果如下


即实现了远程调用,又实现了负载均衡调用,多次刷新通过source即可看出,默认轮训调用到不同服务器。
OpenFeign超时控制
OpenFeign 客户端的默认超时时间为 1 秒钟,如果服务端处理请求的时间超过 1 秒就会报错。为了避免这样的情况,我们需要对 OpenFeign 客户端的超时时间进行控制。 通过一个实例,来演示 OpenFeign 是如何进行超时控制的。- 在所有的服务提供者(服务端)的
<font style="color:rgb(68, 68, 68);">BookController </font>中添加一个响应时间为 5 秒的服务,代码如下。
//超时测试,该服务的响应时间为 5 秒@RequestMapping(value = "/book/feign/timeout")public String BookFeignTimeout() {try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}return "spring-cloud-eureka-provider-book-9002";}
- 在
spring-cloud-openfeign-consumer-9006的 BookService 接口中添加以下代码,绑定服务端刚刚添加的超时服务。
@RequestMapping(value = "/book/feign/timeout")public String BookFeignTimeout();
- 在
spring-cloud-openfeign-consumer-9006的 BookController接口中添加以下代码,绑定服务端刚刚添加的超时服务。
@RequestMapping(value = "/book/feign/timeout")public String bookFeignTimeout(){return bookService.bookFeignTimeout();}
feign:client:config:default:#指的是建立连接后从服务器读取到可用资源所用的时间ConnectTimeOut: 7000#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间ReadTimeOut: 7000
配置完毕后即可调整超时时间请求我们所编写的超时服务,看是否生效
OpenFeign日志增强
OpenFeign 提供了日志打印功能,我们可以通过配置调整日志级别,来了解请求的细节。 Feign 为每一个 FeignClient 都提供了一个 feign.Logger 实例,通过它可以对 OpenFeign 服务绑定接口的调用情况进行监控。 OpenFeign 日志打印功能的开启方式比较简单,下面我们就通过一个实例进行演示。- 修改模块
spring-cloud-openfeign-consumer-9006配置文件
以上配置说明如下:
logging:level:#feign 日志以什么样的级别监控该接口com.chen.springcloudopenfeignconsumer9006.service.BookService: debug
- com.chen.springcloudopenfeignconsumer9006 是开启 @FeignClient 注解的接口(即服务绑定接口)的完整类名。也可以只配置部分路径,表示监控该路径下的所有服务绑定接口
- debug:表示监听该接口的日志级别。
- 创建配置类
在config包中创建ConfigBean
该配置的作用是通过配置的 Logger.Level 对象告诉 OpenFeign 记录哪些日志内容。 Logger.Level 的具体级别如下:
@Configurationpublic class ConfigBean {/*** OpenFeign 日志增强* 配置 OpenFeign 记录哪些内容*/@BeanLogger.Level feginLoggerLevel() {return Logger.Level.FULL;}}
- NONE:不记录任何信息。
- BASIC:仅记录请求方法、URL 以及响应状态码和执行时间。
- HEADERS:除了记录 BASIC 级别的信息外,还会记录请求和响应的头信息。
- FULL:记录所有请求与响应的明细,包括头信息、请求体、元数据等等。
- 启动
spring-cloud-openfeign-consumer-9006访问 http://127.0.0.1:9006/book/get/1。去ieda控制台可以查看如下日志信息,至此日志管理配置完毕。
2022-10-11 10:26:23.565 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] ---> GET http://SPRING-CLOUD-EUREKA-PROVIDER-BOOK-9002/book/get/1 HTTP/1.12022-10-11 10:26:23.566 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] ---> END HTTP (0-byte body)2022-10-11 10:26:23.583 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] <--- HTTP/1.1 200 (17ms)2022-10-11 10:26:23.583 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] connection: keep-alive2022-10-11 10:26:23.583 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] content-type: application/json2022-10-11 10:26:23.583 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] date: Tue, 11 Oct 2022 02:26:23 GMT2022-10-11 10:26:23.583 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] keep-alive: timeout=602022-10-11 10:26:23.584 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] transfer-encoding: chunked2022-10-11 10:26:23.584 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get]2022-10-11 10:26:23.584 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] {"id":"1","name":"《西游记》","author":"吴承恩","price":"55","publishDate":"2022-09-26 00:00:00","count":10,"source":"spring-cloud-eureka-provider-book-8002"}2022-10-11 10:26:23.584 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] <--- END HTTP (166-byte body)
上方是通过类+配置的方式配置好的,我们也可以通过纯配置的方式配置,配置信息如下:
# 开启feign的日志监控feign:client:config:default.loggerLevel: FULLlogging:level:# feign日志以什么级别监控哪个接口cn.ideal.springcloud.service.PaymentFeignService: debug
