gpt4 book ai didi

java - Spring Webflux 或非阻塞模式不能不利于扩展

转载 作者:行者123 更新时间:2023-12-04 20:50:55 25 4
gpt4 key购买 nike

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

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

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

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

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

最后,在 Spring Reactor 中的 X 请求时,是否只创建 1 个线程来运行处理程序而不是传统的 X 线程?在那种情况下,如果有人不小心写了阻塞代码,那是不是意味着每个后续请求都会排队?

最佳答案

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

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

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

  • The reactor pattern and non blocking IO
  • Unix Network Programming
  • Kotlin Webflux
  • 稍微偏离主题但仍然是一个非常突出的例子:Don't Block the Event Loop (NodeJS)
  • 关于java - Spring Webflux 或非阻塞模式不能不利于扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51219732/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com