• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

spring-webflux理解

武飞扬头像
土豆怎么做都好吃
帮助1

了解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 等思想即可。
基于此规范,有一些的实现,比如

  1. Reactor 是基于 Reactive Streams 一套 反应式编程框架(spring子项目)
  2. RxJava,RxJava虽然是java ractive编程的领路人,并且RxJava跟Project Reactor 3.0 基本是等价的。但是考虑到Spring生态的强大,估计其前途不会太光明了。
  3. 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
系列文章
更多 icon
同类精品
更多 icon
继续加载