作者 xqlee
浏览次数 371


Spring WebFlux

spring boot2.0 spring5.0
1.Spring WebFlux简介

  包含在Spring框架中的原始Web框架Spring Web MVC是为Servlet API和Servlet容器而设计的。 反过来的堆栈,Web框架,Spring WebFlux,稍后在版本5.0中添加。 它是完全非阻塞的,支持反向流反向压力,并在诸如Netty,Undertow和Servlet 3.1+容器之类的服务器上运行。

  这两个Web框架镜像了Spring模块的名称spring-webmvc和spring-webflux,并在Spring框架中并存。 每个模块都是可选的。 应用可以使用一个或另一个模块,或者在一些情况下可以使用例如。 具有反应WebClient的Spring MVC控制器。

  除了Web框架之外,Spring WebFlux还提供了用于执行HTTP请求的WebClient,用于测试Web端点的WebTestClient以及客户端和服务器反应的WebSocket支持。

2.为何要新增一个web框架?

  答案的一部分是需要一个非阻塞的Web栈来处理与少量线程的并发,并以较少的硬件资源进行扩展。 Servlet 3.1确实为非阻塞I / O提供了API。但是,使用它会远离Servlet API的其他部分,其中合同是同步的(Filter,Servlet)或阻塞(getParameter,getPart)。这是新的通用API作为任何非阻塞运行时基础的动机。这一点很重要,因为Netty这样的服务器在异步非阻塞空间中已经建立起来了。

  答案的另一部分是功能编程。很像在Java 5中添加注释创造的机会 - 例如。注释的REST控制器或单元测试,在Java 8中添加lambda表达式为Java中的功能API创造了机会。这对于非阻塞应用程序和连续样式API是一个福音 - 由CompletableFuture和ReactiveX普及,允许异步逻辑的声明性组合。在编程模型级别,Java 8启用了Spring WebFlux,可以为注释控制器提供功能性的Web端点。

3.Reactive什么和为什么?

  我们触及非阻塞和功能,但为什么反应性,我们的意思是什么?

  术语“反应性”是指围绕响应变化构建的编程模型 - 网络组件对I / O事件的响应,UI控制器对鼠标事件的反应等。在这个意义上,非阻塞是反应的,因为不是被阻止现在在作为操作完成或数据变得可用的响应通知的模式。

  还有一个重要的机制,我们在春季团队与“反应”相关联,这是非阻碍的背压。在同步的命令式代码中,阻止调用可以作为强制呼叫者等待的背部压力的自然形式。在非阻塞代码中,重要的是控制事件的速率,以便快速生产者不会压倒其目的地。

  活动流是一种小规模,也是Java 9中采用的,它定义了具有背压的异步组件之间的交互。例如,作为发布者的数据存储库可以产生数据,作为订阅者的HTTP服务器可以写入响应。活动流的主要目的是允许用户控制发布商产生数据的速度或速度。

提示:
常见的问题:如果发布商不能放慢下去呢?
活动流的目的只是建立机制和边界。 如果发布商不能放慢速度,那么它必须决定是缓冲还是丢弃还是失败。

4.Reactive API

  活动流对互操作性起着重要作用。图书馆和基础架构组件感兴趣,但作为应用程序API不太有用,因为它的级别太低。什么应用程序需要更高级别和更丰富的功能API来构成异步逻辑 - 类似于Java 8 Stream API,但不仅仅是集合。这是反应库的作用。

  反应堆是Spring WebFlux选择的活动库。它提供了Mono和Flux API类型,可以通过与运算符的ReactiveX词汇对齐的丰富的运算符来处理0..1和0..N的数据序列。反应堆是一个反应流库,因此所有的运营商都支持非阻塞的背压。反应堆非常重视服务器端的Java。它与Spring紧密合作开发。

  WebFlux要求Reactor作为核心依赖关系,但它可以通过Reactive Streams与其他反应库互操作。作为一般规则,WebFlux API接受普通的Publisher作为输入,在内部适应Reactor类型,使用它们,然后返回Flux或Mono作为输出。所以您可以将任何Publisher作为输入传递,您可以对输出应用操作,但是您需要调整输出以与另一个活动库一起使用。无论何时 - 例如注释控制器,WebFlux透明地适用于使用RxJava或其他反应库。有关详细信息,请参阅反应库。

5.编程模型

Spring-Web模块包含基于Spring WebFlux - HTTP抽象,Reactive Streams服务器适配器,反应式编解码器和核心Web API的反应性基础,其角色与Servlet API相当,但具有非阻塞语义。

在此基础上,Spring WebFlux提供了两种编程模型的选择:
  • 注释控制器 - 与Spring MVC相一致,并且基于与spring-web模块相同的注释。 Spring MVC和WebFlux控制器都支持反应(Reactor,RxJava)返回类型,因此不容易将它们分开。一个显着的区别是,WebFlux还支持反应性@RequestBody参数。
  • 功能端点 - 基于lambda的轻量级功能编程模型。将其视为小型库或应用程序可用于路由和处理请求的一组实用程序。注释控制器的巨大差异在于,应用程序负责从开始到结束的请求处理,并通过注释声明意图并被回调。

6.如何选择一个web框架?

  你应该使用Spring MVC还是WebFlux?我们来看几个不同的观点。

  如果您有一个Spring MVC应用程序工作正常,则不需要更改。命令编程是编写,理解和调试代码的最简单方法。您最多可以选择库,因为历史上绝大多数都是阻止。

  如果您已经购买了一个非阻塞的Web堆栈,Spring WebFlux可以提供与这个空间中的其他人一样的执行模式优势,并且还提供了一些选择的服务器 - Netty,Tomcat,Jetty,Undertow,Servlet 3.1+容器,编程模型 - 注释控制器和功能Web端点,以及可选的反应库 - 反应器,RxJava或其他。

  如果您对使用Java 8 lambdas或Kotlin的轻量级功能Web框架感兴趣,则可以使用Spring WebFlux功能Web端点。对于具有较少复杂要求的较小应用或微服务,这也可能是更好的选择,可以从更大的透明度和控制中受益。

  在微服务架构中,您可以使用Spring MVC或Spring WebFlux控制器或Spring WebFlux功能端点组合应用程序。在两个框架中支持相同的基于注释的编程模型,使得重新使用知识更容易,同时为正确的工作选择正确的工具。

  评估应用程序的一种简单方法是检查其依赖性。如果您使用阻塞持久性API(JPA,JDBC)或网络API,则Spring MVC至少是常见架构的最佳选择。在技​​术上,Reactor和RxJava都可以在单独的线程上执行阻塞调用,但是您不会充分利用非阻塞的Web堆栈。

  如果您有一个Spring MVC应用程序调用远程服务,请尝试反向WebClient。您可以从Spring MVC控制器方法直接返回反应类型(Reactor,RxJava或其他)。每个呼叫的延迟或呼叫之间的相互依赖性越大,益处越大。 Spring MVC控制器也可以调用其他无效组件。

  如果你有一个庞大的团队,记住转向非阻塞,功能和声明性编程的陡峭的学习曲线。在没有完全切换的情况下启动的实际方法是使用反应性WebClient。除了这个开始之外,测量的好处。我们预计,对于广泛的应用,转移是不必要的。

  如果您不确定要查找哪些优点,首先了解非阻塞性I / O的工作原理(例如,单线程Node.js上的并发性不是矛盾)及其影响。标签行是“具有较少硬件的缩放”,但不能保证效果,而不是一些网络I / O可能会变慢或不可预测。这个Netflix博客文章是一个很好的资源。

7.Spring WebFlux Server的选择

  Netnet,Undertow,Tomcat,Jetty和Servlet 3.1+容器支持Spring WebFlux。 每个服务器都适用于一个通用的Reactive Streams API。 Spring WebFlux编程模型基于该通用API。
   提示:
  常见的问题:Tomcat和Jetty如何在两个堆栈中使用?
  Tomcat和Jetty的核心是无阻拦。 这是Servlet API,它添加了一个阻塞的外观。 从版本3.1开始,Servlet API为非阻塞I / O添加了一个选择。 然而,其使用需要注意避免
  其他同步和阻塞部件。 因此,Spring的反应式Web堆栈具有低级Servlet适配器来桥接到活动流,但是Servlet API否则不会直接使用。


  默认情况下,Spring Boot 2使用Netty WebFlux,因为Netty在异步非阻塞空间中被广泛使用,并且还提供可共享资源的客户端和服务器。 通过比较Servlet 3.1非阻塞I / O没有太多的使用,因为使用它的条数是如此之高。 Spring WebFlux打开了一条实用的通路。

  Spring Boot中的默认服务器选择主要是关于开箱即用的体验。 应用程序仍然可以选择任何其他受支持的服务器,这些服务器也对性能进行了高度优化,完全无阻塞,并适应了反应流反向压力。 在Spring Boot中,进行切换是微不足道的。

8.性能与规模

  表现有很多特点和意义。 反应和非阻塞通常不会使应用程序运行更快。 在某些情况下,他们可以使用WebClient来并行执行远程调用。 总的来说,需要更多的工作来处理非阻塞的方式,并且可以稍微增加所需的处理时间。

  反应和非阻塞的关键预期好处是能够以小的固定数量的线程和较少的内存进行扩展。 这使得应用程序在负载下更具弹性,因为它们以更可预测的方式扩展。 为了观察这些好处,您需要有一些延迟,包括慢速和不可预测的网络I / O的混合。 这是反应堆栈开始显示其优势的地方,差异可能很大。
暂无评论