不能 Spring Webflux 或非阻塞模式不利于缩放

Couldn't Spring Webflux or Non blocking pattern be bad for scaling

我知道线程是非阻塞的,我们不需要根据 N 个并发请求让线程蔓延,而是我们将我们的任务放在反应式 Web 编程模式中的单个事件循环中。

是的,这会有帮助,但由于事件循环是一个队列,如果要处理的第一个任务永远阻塞怎么办?然后事件循环将永远不会进行,从而结束响应和处理,而不是排队更多任务。是的,超时可能是可能的,但我无法理解事件循环如何成为一个好的解决方案。

假设您有 3 个任务需要 3 秒来等待 IO 并且 运行 每次执行并且它们被提交到事件队列。然后它们仍然需要 9 秒才能被处理,并且在 IO 解析后执行。在使线程阻塞的情况下,这将在 3 秒内解决,因为它们 运行 并发。

我可以看到一个好处是,如果事件循环不是真正的队列,并且在发出任务已准备好处理的信号时,它会分派要处理的任务。但是,在那种情况下,这意味着任务执行的顺序没有得到维护,而且每个任务仍然必须 运行 一个线程才能知道 IO 何时被解析。

可能我没有正确理解事件循环和线程处理。有人可以纠正我吗,因为看起来这种 Reactor 模式似乎会使事情变得更糟。

最后,根据 Spring Reactor 中的 X 请求,是否只为 运行 处理程序创建了 1 个线程而不是传统的 X 线程?那样的话,如果有人不小心写了阻塞代码,那岂不是意味着每个后续请求都会排队?

长时间 运行 任务使用事件循环不是一个好主意。这被认为是一种反模式。通常它仅用于快速拾取即将发生的事件,但如果工作会明显阻塞事件循环,则不会实际执行与这些事件相关的工作。您可能希望使用单独的线程池来执行长 运行 任务。因此,事件循环通常只会 initiate 使用异步和非阻塞结构工作(或者只有在可以非常快地完成时才实际执行工作)并传递更重且可能阻塞的任务到单独的线程池(用于 CPU 密集计算)或操作系统(例如要通过网络发送的数据缓冲区)。

此外,不要被只有一个线程处理事件这一事实所迷惑,它非常快并且通常足以满足要求苛刻的应用程序。像 NodeJS 这样的平台或像 Netty 这样的框架(用于 Akka、Play 框架、Apache Cassandra 等)在他们的核心使用事件循环并取得了巨大的成功。人们应该意识到这样一个事实,即在事件循环内执行阻塞操作通常不是一个好主意。

请查看其中一些帖子以获取更多信息: