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: 9006
spring:
application:
name: spring-cloud-openfeign-consumer-9006
eureka:
client:
#表示是否将自己注册进 EurekaServer默认为true。
register-with-eureka: true
#是否从 EurekaServer 抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-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
@Slf4j
public class BookController {
@Autowired
private 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
@EnableFeignClients
public 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 的具体级别如下:
@Configuration
public class ConfigBean {
/**
* OpenFeign 日志增强
* 配置 OpenFeign 记录哪些内容
*/
@Bean
Logger.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.1
2022-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-alive
2022-10-11 10:26:23.583 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] content-type: application/json
2022-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 GMT
2022-10-11 10:26:23.583 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] keep-alive: timeout=60
2022-10-11 10:26:23.584 DEBUG 92748 --- [nio-9006-exec-4] c.c.s.service.BookService : [BookService#get] transfer-encoding: chunked
2022-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: FULL
logging:
level:
# feign日志以什么级别监控哪个接口
cn.ideal.springcloud.service.PaymentFeignService: debug