Spring Webflux或Non阻止模式是否不利于扩展

时间:2018-07-07 03:47:30

标签: java spring spring-boot reactive-programming project-reactor

我了解到线程是非阻塞的,我们不需要依赖N个并发请求来扩展线程,而是可以将我们的任务放在反应式Web编程模式下的单个事件循环中。

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

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

我从中看到的好处是,如果事件循环不是真正的队列,并且在发出已准备好处理任务的信号时,它将调度要处理的任务。但是,在那种情况下,这将意味着无法维持任务执行的顺序,并且每个任务都必须仍在运行线程,以便能够知道何时解决IO。

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

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

1 个答案:

答案 0 :(得分:6)

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

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

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