spring-webflux理解
了解spring-webflux之前,我们要先了解一个词Reactive Streams
,是一套反应式编程 标准 和 规范,
Reactive Streams 由以下几个组件组成:
- 发布者:发布元素到订阅者
- 订阅者:消费元素
- 订阅:在发布者中,订阅被创建时,将与订阅者共享
- 处理器:发布者与订阅者之间处理数据
其主要的接口有这三个:
- Publisher
- Subscriber
- Subcription
- 被订阅者 (Publisher) 主动推送数据给 订阅者 (Subscriber),触发 onNext() 方法。异常和完成时触发另外两个方法。
- 被订阅者 (Publisher) 发生异常,则触发 订阅者 (Subscriber) 的 onError() 方法进行异常捕获处理。
- 被订阅者 (Publisher) 每次推送都会触发一次 onNext() 方法。所有的推送完成且无异常时,onCompleted()方法将 在最后 触发一次。
如果 Publisher 发布消息太快了,超过了 Subscriber 的处理速度,那怎么办?这就是 Backpressure 的由来。Reactive Programming 框架需要提供 背压机制,使得 Subscriber 能够控制 消费消息 的速度
其中,Subcriber 中便包含了上面表格提到的 onNext、onError、onCompleted 这三个方法。对于 Reactive Streams,只需要理解其思想就可以,包括基本思想以及 Backpressure 等思想即可。
基于此规范,有一些的实现,比如
- Reactor 是基于 Reactive Streams 一套 反应式编程框架(spring子项目)
- RxJava,RxJava虽然是java ractive编程的领路人,并且RxJava跟Project Reactor 3.0 基本是等价的。但是考虑到Spring生态的强大,估计其前途不会太光明了。
- JDK9中Reactive Stream的实现规范 通常被称为 Flow API ,通过java.util.concurrent.Flow 和java.util.concurrent.SubmissionPublisher
类来实现响应式流
WebFlux是spring5以 Reactor 为基础,实现 Web 领域的 反应式编程框架。使用webflux之前,我们先了解Reactor。
Reactor
Reactor 框架主要有两个主要的模块:
- reactor-core
- reactor-netty
前者主要负责 Reactive Programming 相关的 核心 API 的实现,后者负责 高性能网络通信 的实现,目前是基于 Netty 实现的。
在 Reactor 中,经常使用的类并不是很多,主要有以下两个:
- Mono
实现了 org.reactivestreams.Publisher 接口,代表 0 到 1 个元素的 发布者。
- Flux
同样实现了 org.reactivestreams.Publisher 接口,代表 0 到 N 个元素的发表者。
- Scheduler
代表背后驱动反应式流的调度器,通常由各种线程池实现。
我们用reactorApi写下小样例
Mono<String> mono= Mono.just("mono");//发布一个字符串
mono.subscribe(a-> System.out.println(a));//消费一个字符串
Flux<String> fluxs= Flux.just("flux1", "flux2");//发布多个字符串
fluxs.subscribe(a-> System.out.println(a));//消费多个字符串
我们还可以用flux做来一个流式计算
//同步
Flux.just(1,2,3,4,5)
.log()
.map(i->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return i*10;
})
.subscribe(c->log.info("结果:{}",c));
其中的sbcribe就是对flux(发布者的)的订阅消费
webflux
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
引入此依赖,包含了
- reactor-core
- reactor-netty
@GetMapping("/mono")
public Mono<User> monoTest() {
return Mono.just(new User());
}
return时,webflux框架会实现订阅,并将数据返回给调用者相关逻辑,因此使用起来和springmvc没有区别。
但是其内部运行逻辑和mvc有根本区别,webflux要求服务器是基于异步线程模型,比如netty或者servlet3.1 。
在配合netty使用时,
NettyServer的Boss Group线程池内的事件循环会接收这个请求,然后把完成TCP三次握手的连接channel交给WorkerGroup中的某一个事件循环线程组(eventLoop)来进行处理(channelread,该事件处理线程会调用对应的controller进行处理),发布数据时会通过回调触发eventLoop中的事件,所以WebFlux的handler执行是使用Netty的IO线程进行执行的,所以需要注意如果handler的执行比较耗时,会把IO线程耗尽导致不能再处理其他请求,可以通过Reactor的publishOn操作符切换到其他线程池中执行。
适用场景
使用 Spring WebFlux,下游使用的安全认证层、数据访问层框架都必须使用 Reactive API 保证上下游都是匹配的,非阻塞的。然而Spring Data Reactive Repositories 目前只支持 MongoDB、Redis 和Couchbase 等几种不支持事务管理的 NOSQL,技术选型时需要权衡利弊和风险。
Spring MVC能满足场景的,就不需要更改为 Spring WebFlux,毕竟Reactive写法对比原本同步执行的程序写法很不同,而且很多基于Servlet线程模型的库将无法使用,如Spring Transaction……。
需要底层容器的支持(Netty和Servlet3.1 )。
适合应用在 IO 密集型的服务中(IO 密集型包括:磁盘IO密集型, 网络IO密集型),微服务网关就属于网络 IO 密集型,使用异步非阻塞式编程模型,能够显著地提升网关对下游服务转发的吞吐量。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgccahk
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01