Spring 5.0 - WebFlux

最近在做些系统性能瓶颈问题的提升,所以在一些开源社区以及一些著名论坛上看到针对WebFlux的解释和说明,这里不能说不好,总体上就是阻塞-非阻塞性能提升速度更快支持函数式编程反应式编程(Reactive)...人云亦云吗?

一 问题

这里不对一些概念性问题进行解说,主要针对一些疑问来说明?

  1. WebFlux 是什么?
  2. WebFlux 真的快吗?
  3. WebFlux应用场景?

二 知其然不知其所以然

2.1 Spring MVC & Spring WebFlux

我们先来了解下WebFlux: 这是Spring.io 官网提供的解释

spring-reactor.png

结合上图,Spring再解释说明Spring WebFlux的时候与传统web开发使用的Spring MVC模型进行了对比说明:

Spring MVC

  • Spring MVC is built on the Servlet API and uses a synchronous blocking I/O architecture whth a one-request-per-thread model.
  • Spring MVC 构建于 Servlet API 之上,使用的是同步阻塞式 I/O 模型,什么是同步阻塞式 I/O 模型呢?就是说,每一个请求对应一个线程去处理。

这里重点提示一下:

  1. 基于Servlet Contatiners 阻塞式I/O模型;
  2. a one-request-per-thread model 意思就是说:一个请求对应一个线程去处理。

Spring WebFlux

  • Spring WebFlux is a non-blocking web framework built from the ground up to take advantage of multi-core, next-generation processors and handle massive numbers of concurrent connections

  • Spring WebFlux 是一个异步非阻塞式的 Web 框架,它能够充分利用多核 CPU 的硬件资源去处理大量的并发请求。

2.2 Spring WebFlux

The original web framework included in the Spring Framework, Spring Web MVC, was purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework, Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports Reactive Streams back pressure, and runs on such servers as Netty, Undertow, and Servlet 3.1+ containers.
Spring框架中包含的原始Web框架, Spring Web MVC是专门为Servlet API和Servlet容器而构建的。反应性堆栈Web框架Spring WebFlux在更高版本5.0中添加。它是完全非阻塞的,支持 Reactive Streams背压,并在Netty,Undertow和Servlet 3.1+容器等服务器上运行。

2.2 Why was Spring WebFlux created?

以下说明来源于官网

  • Part of the answer is the need for a non-blocking web stack to handle concurrency with a small number of threads and scale with fewer hardware resources. Servlet 3.1 did provide an API for non-blocking I/O. However, using it leads away from the rest of the Servlet API, where contracts are synchronous (Filter, Servlet) or blocking (getParameter, getPart). This was the motivation for a new common API to serve as a foundation across any non-blocking runtime. That is important because of servers (such as Netty) that are well-established in the async, non-blocking space.

简单解释说明一下

  • 就是说一部分原因需要一个非阻塞的web堆栈来处理少量线程的并发性,并使用较少的硬件资源进行扩展。Servlet 3.1确实提供了用于非阻塞I / O的API。但是其中约定是同步的诸如(FilterServlet)以及阻塞的(getParametergetPart),所以使用Servlet 3.1可能会导致不在使用Servlet API 其他部分。这也同样的会促进一个新的通用性的API在任何非阻塞提供一个基础的时机。诸如:服务器(如Netty)在异步、非阻塞空间中已经很好地建立起来。

提炼

  1. 异步非阻塞(non-blocking web stack)
  2. 少量线程数处理并发性(handle concurrency with a small number of threads)
  3. 少量硬件资源提高伸缩性(scale with fewer hardware resources.)
  4. Servlet 3.1 提供一个非阻塞API。
  • The other part of the answer is functional programming. Much as the addition of annotations in Java 5 created opportunities (such as annotated REST controllers or unit tests), the addition of lambda expressions in Java 8 created opportunities for functional APIs in Java. This is a boon for non-blocking applications and continuation-style APIs (as popularized by CompletableFuture and ReactiveX) that allow declarative composition of asynchronous logic. At the programming-model level, Java 8 enabled Spring WebFlux to offer functional web endpoints alongside annotated controllers.

简单解释说明一下

  • 另一部分原因:函数式编程。与在Java5中添加注释创造了机会(如带注释的REST控制器或单元测试)一样,在Java8中添加lambda表达式也为Java中的功能性API创造了机会。这对于非阻塞的应用程序和允许异步逻辑的声明式组合的 (as popularized by CompletableFuture and ReactiveX) 是有益的。在编程模型级别,Java 8支持Spring WebFlux提供功能性的web端点和带注释的控制器。

提炼

  1. 函数式编程(functional programming)
  2. 反应式(Reactive)
    了解以上背景后再说说什么是``Reactive`
  • The term, “reactive,” refers to programming models that are built around reacting to change — network components reacting to I/O events, UI controllers reacting to mouse events, and others. In that sense, non-blocking is reactive, because, instead of being blocked, we are now in the mode of reacting to notifications as operations complete or data.
  • 反应式是指围绕对变化作出反应的编程模型,网络组件对I/O事件作出反应,UI控制器对鼠标事件作出反应,以及其他。从这个意义上说,非阻塞是被动的,因为不是被阻断,而是以操作完成或者数据的形式响应通知。

2.3 WebFlux 的优势&提升性能?

犹如上面介绍:WebFlux 内部使用的是响应式编程(Reactive Programming),以 Reactor 库为基础, 基于异步和事件驱动,可以让我们在不扩充硬件资源的前提下,提升系统的吞吐量和伸缩性。

所以它最终解决的是在很少或者不扩充硬件资源的前提下,提升系统的吞吐量和伸缩性。而不是使得应用程序运行的更快,更不会使得你的接口的请求响应的时间缩短了

下面是官网原文:

  • Performance has many characteristics and meanings. Reactive and non-blocking generally do not make applications run faster. They can, in some cases, (for example, if using the WebClient to execute remote calls in parallel). On the whole, it requires more work to do things the non-blocking way and that can increase slightly the required pro
  • WebFlux 并不能使接口的响应时间缩短,它仅仅能够提升吞吐量和伸缩性
  • The key expected benefit of reactive and non-blocking is the ability to scale with a small, fixed number of threads and less memory.That makes applications more resilient under load, because they scale in a more predictable way.
  • 反应式和非阻塞的主要预期好处是能够使用少量、固定数量的线程和较少的内存进行扩展。这使应用程序在负载下更具弹性,因为它们以更可预测的方式扩展。

三 WebFlux 应用场景

上面说到了, Spring WebFlux 是一个异步非阻塞式的 Web 框架,所以,它特别适合应用在 IO 密集型的服务中,比如微服务网关这样的应用中(Spring cloud gateway)。

3.1 Applicability : WebFlux OR Spring MVC?

官网给出了这么一句话:

  • Spring MVC or WebFlux?
    A natural question to ask but one that sets up an unsound dichotomy. Actually, both work together to expand the range of available options. The two are designed for continuity and consistency with each other, they are available side by side, and feedback from each side benefits both sides. The following diagram shows how the two relate, what they have in common, and what each supports uniquely:

  • 通过这段是我们可以知道,当你问出这个问题的时候,其实这个问题本身就是已经不合理了,所以无论是WebFlux OR Spring MVC 两者设计旨在实现彼此的连续性和一致性,它们是可以并行使用。共同努力扩大了可用选型的范围。

3.2 Concurrency Model ( Spring MVC and Spring WebFlux)

  • Both Spring MVC and Spring WebFlux support annotated controllers, but there is a key difference in the concurrency model and the default assumptions for blocking and threads.(Spring MVC和Spring WebFlux都支持带注释的控制器,但是并发模型以及阻塞和线程的默认假设存在关键差异。)

  • In Spring MVC (and servlet applications in general), it is assumed that applications can block the current thread, (for example, for remote calls), and, for this reason, servlet containers use a large thread pool to absorb potential blocking during request handling.(在Spring MVC(通常是Servlet应用程序)中,假定应用程序可以阻塞当前线程(例如,用于远程调用),因此,servlet容器使用大线程池来吸收请求期间的潜在阻塞。处理。)

  • In Spring WebFlux (and non-blocking servers in general), it is assumed that applications do not block, and, therefore, non-blocking servers use a small, fixed-size thread pool (event loop workers) to handle requests.(在Spring WebFlux(通常是非阻塞服务器)中,假定应用程序未阻塞,因此,非阻塞服务器使用固定大小的小型线程池(事件循环工作器)来处理请求。)

下图是两者的共同点和独自的特性

spring-mvc-webflux.png

官网也提出了很多关于这方面的建议:

We suggest that you consider the following specific points:

*   如果您有运行正常的Spring MVC应用程序,则无需更改。命令式编程是编写,理解和调试代码的最简单方法。您有最大的库选择空间,大多数都处于阻塞状态。

*   如果您已经在购买无阻塞Web堆栈,那么Spring WebFlux在此空间中提供的执行模型优势与其他模型相同,并且还提供服务器选择(Netty,Tomcat,Jetty,Undertow和Servlet 3.1+容器),选择编程模型(带注释的控制器和功能性Web端点),以及选择反应式库(Reactor,RxJava或其他).

*   如果您对与Java 8 lambda或Kotlin一起使用的轻量级功能性Web框架感兴趣,可以使用Spring WebFlux功能性Web端点。对于要求较低复杂性的较小应用程序或微服务(可以受益于更高的透明度和控制)而言,这也是一个不错的选择.

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

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

*   如果您的Spring MVC应用程序具有对远程服务的调用,请尝试使用active `WebClient`。您可以直接从Spring MVC控制器方法返回反应性类型(Reactor,RxJava [或其他]每个呼叫的等待时间或呼叫之间的相互依赖性越大,好处就越明显。Spring MVC控制器也可以调用其他反应式组件.

*   如果您有庞大的团队,请牢记向无阻塞,功能性和声明性编程的过渡过程中的学习曲线陡峭。在没有完全切换的情况下启动的实际方法是使用电抗器`WebClient`。除此之外,从小处着手并衡量收益。我们希望,对于广泛的应用程序,这种转变是不必要的。如果不确定要寻找什么好处,请先了解无阻塞I / O的工作原理(例如,单线程Node.js上的并发性)及其影响.
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容