Spring WebFlux 和 Reactor 的线程模型 [英] Threading model of Spring WebFlux and Reactor

查看:246
本文介绍了Spring WebFlux 和 Reactor 的线程模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前正在使用 Spring 5.0.0.RC2Reactor 3.1.0.M2Spring Boot 2.0.0.M2 试验反应式编程.

Currently experimenting reactive programming with Spring 5.0.0.RC2, Reactor 3.1.0.M2 and Spring Boot 2.0.0.M2.

想知道 WebFlux 和 Reactor 使用并发和线程模型来正确编码应用程序和处理可变状态.

Wondering about the concurrency and threading model used by WebFlux and Reactor to properly code the application and handle the mutable state.

Reactor 文档指出该库被认为是并发不可知的,并提到了调度程序抽象.WebFlux 文档未提供信息.

The Reactor doc states that the library is considered concurrency agnostic and mentions the Scheduler abstraction. The WebFlux doc does not give information.

然而,当通过 Spring Boot 使用 WebFlux 时,定义了一个线程模型.

Yet when using WebFlux through Spring Boot, a threading model is defined.

我的实验结果如下:

  • 该模型既不是 1 个事件线程,也不是 1 个事件线程 + 工作线程
  • 使用了多个线程池
  • reactor-http-nio-3"线程:可能每个核心一个,处理传入的 HTTP 请求
  • Thread-7"线程:用于对 MongoDB 或 HTTP 资源的异步请求
  • "parallel-1" 线程:每个内核一个,由 Reactor 的 Schedulers.parallel() 创建,由延迟运算符等使用
  • 共享的可变状态必须由应用程序同步
  • ThreadLocal(用于应用程序状态、MDC 日志记录等)不是请求范围的,因此不是很有趣
  • The model is neither 1 event thread, nor 1 event thread + workers
  • Several thread pools are used
  • "reactor-http-nio-3" threads: probably one per core, handle the incoming HTTP requests
  • "Thread-7" threads: used by async requests to MongoDB or HTTP resources
  • "parallel-1" threads: one per core, created by Schedulers.parallel() from Reactor, used by delay operators and such
  • Shared mutable state must be synchronized by the application
  • ThreadLocal (for application state, MDC logging, etc) are not request scoped, so are not very interesting

这是正确的吗?WebFlux 的并发和线程模型是什么:例如默认线程池是什么?

Is this correct ? What is the concurrency and threading model of WebFlux: for example what are the default thread pools?

感谢您提供信息

推荐答案

提问后,目前的文档确实提供了一些关于并发模型的线索 和人们可以期待的线程(但我仍然认为对发生的事情的更清晰/更好的描述Spring 新人将高度赞赏多线程视角下的场景下).

After the question, the present documentation does provide some clues about the concurrency model and the threads one could expect (but I still think that clearer/better descriptions of what happens under-the-scene from a multi-threading perspective would be highly appreciated by Spring newcomers).

它讨论了 Spring MVC 和 Spring WebFlux 之间的区别(1-thread-per-request 模型与事件循环):

It discusses the difference between Spring MVC and Spring WebFlux (1-thread-per-request model vs. event-loop):

在 Spring MVC 和一般的 servlet 应用程序中,假设应用程序可能会阻塞当前线程,例如对于远程调用,因此 servlet 容器使用大型线程池来吸收请求处理期间的潜在阻塞.

In Spring MVC, and servlet applications in general, it is assumed that applications may block the current thread, e.g. for remote calls, and for this reason servlet containers use a large thread pool, to absorb potential blocking during request handling.

在 Spring WebFlux 和一般的非阻塞服务器中,假设应用程序不会阻塞,因此非阻塞服务器使用一个小的、固定大小的线程池(事件循环工作线程)来处理请求.调用阻塞 API

In Spring WebFlux, and non-blocking servers in general, it is assumed that applications will not block, and therefore non-blocking servers use a small, fixed-size thread pool (event loop workers) to handle requests. Invoking a Blocking API

但请注意,Spring MVC 应用程序也可以引入一些异步性(参见 Servlet 3 Async).我建议这个演示文稿进行讨论Servlet 3.1 NIO 和 WebFlux.

But notice that Spring MVC apps can also introduce some asynchronicity (cf., Servlet 3 Async). And I suggest this presentation for a discussion wrt Servlet 3.1 NIO and WebFlux.

回到文档:它还表明,在使用响应式流时,您有一些控制权:

Back to the docs: it also suggests that, when working with reactive streams, you have some control:

如果您确实需要使用阻塞库怎么办?

Reactor 和 RxJava 都提供了 publishOn 操作符来继续在不同的线程上处理.

Both Reactor and RxJava provide the publishOn operator to continue processing on a different thread.

(有关此的更多详细信息,请参阅在 Reactor 中调度)

(For more details on this, refer to scheduling in Reactor)

它还讨论了您可能期望在 WebFlux 应用程序中使用的线程(粗体是我的):

It also discusses the threads you may expect in WebFlux applications (bold is mine):

线程模型

您希望在运行 Spring WebFlux 的服务器上看到哪些线程?

What threads should you expect to see on a server running with Spring WebFlux?

  • 在普通"的 Spring WebFlux 服务器上(例如,没有数据访问,也没有其他可选的依赖项),您可以期望 一个线程用于服务器,另外几个线程用于请求处理(通常与 CPU 的数量一样多)核心).但是,Servlet 容器可以从更多线程开始(例如 Tomcat 上的 10 个线程),以支持 servlet、阻塞 I/O 和 servlet 3.1、非阻塞 I/O 使用.
  • 反应式WebClient事件循环样式运行.所以你会看到一个固定数量的与此相关的处理线程,例如带有 Reactor Netty 连接器的reactor-http-nio-".但是,如果客户端和服务器都使用 Reactor Netty,则默认情况下两者将共享事件循环资源.
  • Reactor 和 RxJava 提供线程池抽象,称为调度程序,与用于将处理切换到不同线程池的publishOn 运算符一起使用.调度程序的名称暗示了特定的并发策略,例如并行"用于线程数量有限的 CPU 密集型工作,或者 弹性"用于 I/O 密集型工作 并带有大量线程.如果您看到此类线程,则表示某些代码正在使用特定的线程池调度程序策略.
  • 数据访问库和其他第 3 方依赖项也可能创建和使用自己的线程.
  • On a "vanilla" Spring WebFlux server (e.g. no data access, nor other optional dependencies), you can expect one thread for the server, and several others for request processing (typically as many as the number of CPU cores). Servlet containers, however, may start with more threads (e.g. 10 on Tomcat), in support of both servlet, blocking I/O and servlet 3.1, non-blocking I/O usage.
  • 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 and RxJava provide thread pool abstractions, called Schedulers, to use with the publishOn operator that is used to switch processing to a different thread pool. The schedulers have names that suggest a specific concurrency strategy, e.g. "parallel" for CPU-bound work with a limited number of threads, or "elastic" for I/O-bound work with a large number of threads. If you see such threads it means some code is using a specific thread pool Scheduler strategy.
  • Data access libraries and other 3rd party dependencies may also create and use threads of their own.

部分,您可以通过配置来配置线程模型的细节

In part, you can configure the details of the threading model via configuration

要为服务器配置线程模型,您需要使用特定于服务器的配置 API,或者如果使用 Spring Boot,请检查每个服务器的 Spring Boot 配置选项.WebClient 可以直接配置.对于所有其他库,请参阅它们各自的文档.

To configure the threading model for a server, you’ll need to use server-specific config APIs, or if using Spring Boot, check the Spring Boot configuration options for each server. The WebClient can be configured directly. For all other libraries, refer to their respective documentation.

此外,例如讨论 Spring 中的默认线程数启动 2.0 反应式 webflux 配置亮点,

Moreover, as e.g. the discussion Default number of threads in Spring boot 2.0 reactive webflux configuration highlights,

请求处理的默认线程数由底层 Web 服务器决定;默认情况下,Spring Boot 2.0 使用的是 Reactor Netty,它使用的是 Netty 的默认值

The default number of threads for request handling is determined by the underlying web server; by default, Spring Boot 2.0 is using Reactor Netty, which is using Netty's defaults

这是默认组件及其默认值(以及整体配置,包括通过注解透明注入的配置)的问题——这也可能在 Spring/Boot 和相应依赖项的版本之间发生变化.这么说吧,你的猜测似乎是正确的.

it is a matter of default components and their defaults (and overall configuration, including that injected transparently through annotations) -- which may also change across versions of Spring/Boot and corresponding dependencies. Said that, your guesses seem correct.

这篇关于Spring WebFlux 和 Reactor 的线程模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆