java处理异步非阻塞请求_Spring WebFlux 的异步非阻塞处理

前言

随着 Web Servlet 技术栈的不断发展实现了异步处理与非阻塞 IO,但是其异步是不彻底的,因为受制于 Servlet 规范本身,比如其规范是同步的(Filter,Servlet)或阻塞(getParameter,getPart)。

所以新的使用少量线程和较少的硬件资源来处理并发的非阻塞 Web 技术栈应运而生- WebFlux,其是与 Servlet 技术栈并行存在的一种新的技术,其基于 JDK8 函数式编程与 Netty 实现天然的异步、非阻塞处理。

本 Chat 则主要讲解 Spring 框架 5.0 中引入的新的 WebFlux 技术栈,内容如下:

WebFlux 存在的价值与意义是什么

WebFlux 的并发模型是怎样的

WebFlux 的的两种编程模型是怎样的

如何使用 WebFlux 进行编程

WebFlux 内部实现原理是怎么样的

WebFlux 的适用场景是什么

Spring WebFlux 概述

Spring 框架中包含的原始 Web 框架 Spring Web MVC 是专为 Servlet API 和 Servlet 容器构建的。反应式栈的 Web 框架 Spring WebFlux 则是在 Spring 5.0 版中才新添加的,它是完全无阻塞的,并且支持 Reactive Streams 回压,并可以在 Netty 、Undertow 和 Servlet 3.1+容器等服务器上运行,其中 WebFlux 中的 Flux 是源自 Reactor 库中的 Flux 流对象。如下图左侧是 spring-webmvc 模块提供的传统的基于 Servlet 的 Spring MVC 技术栈,右侧是 spring-webflux 模块的反应式编程技术栈(reactive stack)。

b053c6f3547783f7410cc054128698f7.png

Web 技术栈对比

Servlet API 最初是为了通过 Filter->Servlet 链进行单次传递而构建的。 Servlet 3.0 规范中添加的异步请求处理允许应用程序及时退出 Filter-Servlet 链(及时释放容器线程),但保持响应打开以便异步线程进行后续处理。 Spring MVC 的异步处理支持是围绕该机制构建的。当 controller 返回 DeferredResult 时,将退出 Filter-Servlet 链,并释放 Servlet 容器线程。稍后,当设置 DeferredResult 时,会对请求进行重新分派,使用 DeferredResult 值(就像 controller 返回它一样)以恢复处理。

相比之下,Spring WebFlux 既不是基于 Servlet API 构建的,也不需要这样的异步请求处理功能,因为它在设计上是异步的。其对异步的处理是内置于框架规范中的,并通过请求处理的所有阶段进行内在支持。

从编程模型的角度来看,Spring MVC 和 Spring WebFlux 都支持异步和反应式作为 controller 方法中的返回值。 Spring MVC 甚至支持流媒体,包括反应性回压功能,但是其对响应的写入仍然是阻塞的(并且在单独的线程上执行), Servlet 3.1 确实为非阻塞 I / O 提供了 API,但是使用它会远离 Servlet API 的其余部分,比如其规范是同步的(Filter,Servlet)或阻塞的(getParameter,getPart)。WebFlux 则不同,其依赖于非阻塞 I / O,并且每次写入都不需要额外的线程进行支持。

Reactive 编程 & Reactor 库

术语 Reactive(反应式编程),其是指围绕变化做出反应的编程模型 - 比如对 I / O 事件做出反应的网络组件,对鼠标事件做出反应的 UI 控制器等。从这个意义上说,非阻塞是被动的,因为我们现在处于一种模式,即在操作完成或数据可用时对结果作出反应。

Reactive Streams 是一个规范(在 Java 9 中也采用),用于定义具有回压的异步组件之间的交互。例如,数据存储库(充当发布者)可以产生数据(从数据库迭代出数据),然后 HTTP 服务器(充当订阅服务器)可以把迭代出的数据写入请求响应中,那么从数据库里面迭代数据的快慢就取决于 HTTP 服务器向响应对象里面写入的快慢。 Reactive Streams 的主要目的是让订阅者控制发布者生成数据的速度。

另外 Reactive Streams 的目的是建立回压的一种机制和一个边界限制,如果发布者不能够降低自己生产数据的速度,那么它要决定是否要缓存或者丢失或者报错失败。

Reactive Streams 在互操作性方面发挥着重要作用。它对库和基础架构组件很有用,但作为应用程序 API 不太有用,因为它太低级了。应用程序需要更高级别和更丰富的功能 API 来组成异步逻辑 - 类似于 Java 8 Stream API,但其不仅适用于集合。这是 Reactive 库所扮演的角色,Java 中已有的 Reactive 库有 Reactor 和 RxJava,Spring 团队认为 Reactor 是 Spring WebFlux 的首选 reactive 库。Reactor 提供 Mono 和 Flux API 流类型,其提供了与 ReactiveX 词汇表对齐的丰富运算符,处理 0..1(Mono)和 0..N(Flux)的数据序列。 Reactor 是一个 Reactive Streams 库,因此它的所有运营商都支持非阻塞反压功能,它是与 Spring 密切合作开发的。

WebFlux 要求 Reactor 作为核心依赖,但它可以通过 Reactive Streams 与其他反应式库互(比如 RxJava)交互操作。作为一般规则,WebFlux API 接受普通 Publisher 作为输入,在内部使其适配 Reactor 类型,使用它并返回 Flux 或 Mono 作为输出。因此,您可以将任何 Publisher 作为输入传递,并且可以对输出应用操作符,但是您需要调整输出以与其他类型的反应库(例如 RxJava)一起使用。只要可行(例如带注解的 controller),WebFlux 就会透明地适配 RxJava 或其他反应库的使用。

WebFlux 服务器

Spring WebFlux 可以在 Tomcat、Jetty、Servlet 3.1+容器以及非 Servlet 运行时(如 Netty 和 Undertow)上运行。所有服务器都适用于低级别的通用 API,因此可以跨服务器支持更高级别的编程模型。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值