一、概述
当我们使用SpringCloud Gateway的时候,无法避免会遇到Mono和Flux这两个类,其实它们都来自Spring WebFlux,而SpringCloud Gateway正是基于WebFlux来构建的一个高性能网关。
- 什么是Spring WebFlux响应式编程
- Mono常用API
- Flux常用API
- 总结Mono和Flux
二、正文
1、什么是Spring WebFlux响应式编程
上图来自Spring官网,展示了传统的 SpringMVC 和 WebFlux 之间的区别。
WebFlux 底层使用 Netty,这点也和我们传统的 SpringMVC 不一样,不过默认端口都是 8080。
Spring WebFlux 是一个异步非阻塞式 IO 模型,通过少量的容器线程就可以支撑大量的并发访问,所以 Spring WebFlux 可以有效提升系统的吞吐量和伸缩性,特别是在一些 IO 密集型应用中,例如微服务网关 Spring Cloud Gateway 就使用了 WebFlux,这样可以有效提升网管对下游服务的吞吐量。
WebFlux底层使用Reactor这套Java响应式编程框架,通过异步来提高系统吞吐量,涉及发布者和消费者两个基础概念,有点类似消息队列,基于发布/订阅模式。
日常我们一般只会接触到Reactor中的发布者,即Mono和Flux,功能类似Future,区别在于前者可以响应0-1个元素,后者响应0-N个元素,它们的使用方式类似Java 8的 Stream。
2、 Mono常用API
Mono.just()
功能:使用已知内容创建Mono实例
Mono<String> just = Mono.just("hello world");
just.subscribe(System.out::println);
运行代码将打印“hello world”
Mono.defer()
功能:传入一个生产者,即创建Mono的方式,每次消费都会新建一个Mono实例,而just消费多少次都只有一个实例
Mono<String> defer = Mono.defer(() -> {
return Mono.just("time: " + new Date().toString());
});
defer.subscribe(System.out::println);
Thread.sleep(1000);
defer.subscribe(System.out::println);
两次消费打印的时间将不同
Mono.empty()
功能:创建一个不含任何元素的Mono
Mono.empty().subscribe(System.out::println);
什么都不会打印
doOnError()
功能:在消费之前发生异常时执行的逻辑
Mono.just("hello world").doFirst(() -> {
int w = 1 / 0 ;
}).doOnError(throwable -> {
System.out.println("error is : " + throwable.getMessage());
}).subscribe(System.out::println);
执行代码,将打印除零异常,并且不会执行消费
3、 Flux常用API
Flux.just()
功能:使用已知内容创建Flux实例
Flux.just("abc","efg","rst").subscribe(System.out::println);
运行代码将打印三行字符串
Flux.range()
功能:创建一定的数字范围
Flux.range(1,9).subscribe(System.out::println);
运行代码将打印1到9
Flux.fromArray()
功能:根据数组来创建Flux实例
String[] arr = {"A","B","C"};
Flux.fromArray(arr).subscribe(System.out::println);
4、总结Mono和Flux
两个类的API大部分都一样,和Stream高度类似,包括创建、异常处理、遍历、转换、过滤、压平等等。