目前正在尝试使用 Spring 5.0.0.RC2 , Reactor 3.1.0.M2 和 Spring Boot
2.0.0.M2
进行反应式编程。
想知道WebFlux和Reactor使用的 并发和线程模型 来正确编写应用程序并处理可变状态。
Reactor文档指出该库被认为与并发无关,并提到了Scheduler抽象。WebFlux文档不提供信息。
但是,通过Spring Boot使用WebFlux时,会定义一个线程模型。
从我的实验中,我得到了:
这样对吗 ?WebFlux的并发和线程模型是什么:例如,默认的线程池是什么?
感谢您的信息
在提出问题之后,本文档的确提供了一些有关并发模型和线程可能期望的线索(但我仍然认为,从多线程的角度对幕后发生的事情进行更清晰/更好的描述将受到高度赞赏。春季新人)。
它讨论了Spring MVC和Spring WebFlux(每请求1线程模型与事件循环)之间的区别:
通常在Spring
MVC和servlet应用程序中,假定应用程序可能会阻塞当前线程(例如,用于远程调用),因此,servlet容器使用大线程池来吸收请求处理期间的潜在阻塞。在Spring
WebFlux和一般非阻塞服务器中,假定应用程序不会阻塞,因此非阻塞服务器使用固定大小的小型线程池(事件循环工作程序)来处理请求。调用阻止API
但是请注意,Spring MVC应用程序还可能引入一些异步性(请参阅Servlet
3异步)。我建议在演示文稿时讨论Servlet 3.1 NIO和WebFlux。
回到文档:它还建议在使用反应流时,您可以控制一些:
如果确实需要使用阻止库怎么办?
Reactor和RxJava都提供了publishOn运算符以继续在其他线程上进行处理。
(有关更多信息,请参阅Reactor中的调度)
它还讨论了WebFlux应用程序中可能需要的线程( 粗体 是我的):
线程模型
您期望在运行Spring WebFlux的服务器上看到哪些线程?
- 在“原始” Spring WebFlux服务器上(例如,没有数据访问权限,也没有其他可选的依赖项),您可以期望
该服务器有一个线程,而其他几个则用于请求处理(通常与CPU核心数一样多)
。但是,Servlet容器可能以更多线程(例如Tomcat上为10)开始,以同时支持Servlet,阻塞I / O和Servlet 3.1,即非阻塞I
/ O使用。- The reactive WebClient operates in event loop style. So you’ll
see a small, fixed number of processing threads related to that, e.g.
“reactor-http-nio-” with the Reactor Netty connector. However if Reactor
Netty is used for both client and server, the two will share event loop
resources by default.- Reactor和RxJava提供称为 调度程序的 线程池抽象,以与 publishOn运算符 配合使用,该
运算符用于将处理切换到另一个线程池 。该 调度有提出一个具体的并发策略的名称 ,如 “平行”的CPU限制的工作
与线程的数量有限,或 “弹性”为I / O密集型工作, 有大量的线程。如果看到这样的线程,则意味着某些代码正在使用特定的线程池调度程序策略。- 数据访问库和其他第三方依赖性也可以创建和使用自己的线程 。
您可以部分地通过配置来配置线程模型的详细信息
要为服务器配置线程模型,您需要使用服务器特定的配置API,或者,如果使用Spring Boot,请检查每台服务器的Spring
Boot配置选项。可以直接配置WebClient。对于所有其他库,请参阅其各自的文档。
此外,例如在Spring Boot2.0反应式Webflux配置中的默认线程数讨论中 ,
用于请求处理的默认线程数由基础Web服务器确定。默认情况下,Spring Boot 2.0使用的是Reactor
Netty,后者使用的是Netty的默认值
这是默认组件及其默认值(以及整体配置,包括通过注释透明注入的默认配置)的问题-在Spring /
Boot版本和相应的依赖项之间,它们也可能会发生变化。话虽如此,您的猜测似乎是正确的。
目前正在使用Spring 5.0.0.rc2、Reactor 3.1.0.m2和Spring Boot 2.0.0.m2进行反应编程实验。 对WebFlux和Reactor所使用的并发和线程模型感到疑惑,以正确地对应用程序进行编码并处理可变状态。 Reactor doc声明库被认为是并发不可知的,并且提到了调度器抽象。WebFlux文档不提供信息。 然而,当通过Spring Boot使用WebFl
早期除了reactor线程外,还设置了writer写成,用于监听worker进程的PIPE,写回TCP客户端。 1.6.12后将这2个角色做了合并,直接在reactor进程内监听PIPE,写回TCP客户端。 合并后的好处是,recv/send/close都是在同一个线程内完成的,不存在之前复杂的时序问题。一切变得更加简单了。另外outbuffer和sendfile也可以更轻松实现。 swoole_
反应器-http-epoll-1 reactor-http-epoll-2 reactor-http-epoll-3 reactor-http-epoll-4 我知道我可以使用Reactor调度器来卸载阻塞工作。我的问题更多的是--这4个线程是什么,我们在哪里有这种配置?
之前提到Vert.x API是事件驱动 - 当他们都可用时,Vert.x传递事件给处理程序。 在大多数情况下Vertx要求使用一种称为event loop线程的处理程序。 如无有 Vert.x 或您的应用程序块中,event loop可以欢快地运行将事件传递给不同的处理程序提供事件陆续到达。 因为没有阻塞,event loop可以在短时间内提供大量的事件。例如一个单一的event loop可以非常
本章介绍 线程模型的总览 EventLoop 并发 任务执行 任务调度 线程模型定义了应用或者框架如何执行你的代码,所以选择线程模型极其重要。Netty 提供了一个简单强大的线程模型来帮助我们简化代码。所有 ChannelHandler,包括业务逻辑,都保证由一个 Thread 同时执行特定的 Channel。这并不意味着Netty不能使用多线程,只是 Netty 限制每个Channel 都由一个
前面讲到,整个libevent本身就是一个Reactor,因此本节将专门对Reactor模式进行必要的介绍,并列出libevnet中的几个重要组件和Reactor的对应关系,在后面的章节中可能还会提到本节介绍的基本概念。 1 Reactor的事件处理机制 首先来回想一下普通函数调用的机制:程序调用某函数?函数执行,程序等待?函数将结果和控制权返回给程序?程序继续处理。 Reactor释义“反应堆”