什么是 Spring WebFlux?
Spring WebFlux 可以定义为已知和广泛使用的 Spring MVC 的“并行”版本,主要区别在于支持反应式 NIO 流和支持背压概念以及默认嵌入其体系结构中的 Netty 服务器.
从 Spring Framework 5.0 版本开始,除了已经存在的 Servlet 结构之外,我们还有一个反应部分,其中每个模块都是可选的,您可以在应用程序中使用 Servlet 部分来反应部分,甚至可以同时使用两者。
这可以通过下图得到最好的例证:
Webflux 位于堆栈的“反应部分”,其中:
- 我们使用 Netty / Undertow 作为服务器而不是 servlet;
- 我们不使用 Servlet API(它是阻塞的),我们使用 Reactive Streams;
- 我们开始使用路由器功能而不是@Controller
重要的是要注意,我们可以只使用一种甚至两种架构,充分利用两者。
Spring Webflux 是由于需要非阻塞应用程序而开发的,这些应用程序能够同时使用少量线程并且可以使用一些硬件资源运行。
在 Servlet 3.1 中提供了一个 NIO API,但它的使用与 API 的其余部分以及 Servlet 背后的所有概念不匹配,Servlet 具有阻塞契约,例如 getPart 和 getParameter,并且它们的契约是使用 Filter 和 Servlet 以同步方式定义的举个例子。
这些因素对于新 API 的开发具有决定性作用,该 API 将独立于执行时间并以非阻塞方式使用,这对于在异步和非阻塞操作中整合自身的服务器是可能的,例如 Netty。
另一个原因是 WebFlux 使函数式/反应式编程概念更容易理解和使用。添加了 Java 8 的功能特性(例如 lambda 表达式、流、Optional ...)。在风格/编程模型方面,Java 8 允许 Spring WebFlux 在应用程序中具有功能端点和带注释的控制器。
它是如何工作的?
在 MVC 模型中,请求的工作方式如下:
客户端发出一个请求,该请求由 TomCat 接收并由线程池控制,该请求被传递给 Dispatcher Servlet,该 Servlet 将该请求分派到 RequestMapping 中的相应端点,该请求将在 Controller 处接收,该 Controller 将处理该服务最后将返回一个响应。这整个过程是以阻塞的方式发生的,即前一个请求完成后,另一个请求才会进入。
在 Webflux 中,这会有点不同:
客户端发出请求到我们的非阻塞服务器(Netty),它内部有一个事件循环来管理这些请求,然后它传递给 reactor-netty(它使这个接口与应用程序反应),它通过到调度程序处理程序,它通过功能端点将生成此响应,并且在整个过程中,可以发出新请求,因为它是一个非阻塞架构。
我们可以说 Spring WebFlux 使用了最好的 servlet 栈及其响应式特性,正如我们在 Spring 文档下图中所见:
在 MVC 方面,我们有命令式编程、JDBC/JPA 和其他阻塞依赖项/进程。
在 Spring Webflux 方面,我们有功能端点、事件循环、Netty 和一些已经存在于 MVC 中但在 Webflux 中开始得到更大支持的功能,例如 Reactive Clients。