如何实现ReactiveMongo,使其被视为非阻塞?

无聊

阅读有关Play框架和ReactiveMongo的文档后,我相信ReactiveMongo的工作方式是使用很少的线程并且从不阻塞。

但是,似乎从Play应用程序到Mongo服务器的通信必须在某处的某个线程上进行如何实施?链接到Play,ReactiveMongo,Akka等源代码的链接也将非常感谢。

Play框架在此页面上包含有关线程池的一些文档它开始于:

从下至上,播放框架是一个异步Web框架。流是使用迭代器异步处理的。由于play-core中的IO永远不会阻塞,因此Play中的线程池已调整为使用比传统Web框架更少的线程

然后,它谈到了ReactiveMongo:

典型的Play应用程序将阻止的最常见位置是与数据库对话时。不幸的是,没有一个主要数据库为JVM提供异步数据库驱动程序,因此对于大多数数据库,您唯一的选择是使用阻塞IO。ReactiveMongo是一个明显的例外,它是MongoDB的驱动程序,它使用Play的Iteratee库与MongoDB进行通信。

以下是有关使用期货的说明:

请注意,因此您可能会倾向于将阻止代码包装在Future中。这并不是说非阻塞,而是意味着阻塞将在不同的线程中发生您仍然需要确保在那里使用的线程池有足够的线程来处理阻塞。

在“处理异步结果”页上的Play文档中有类似的注释

您不能通过将其包装在Future中而神奇地将同步IO变成异步。如果您不能更改应用程序的体系结构以避免阻塞操作,则在某个时候必须执行该操作,并且该线程将阻塞因此,除了将操作封装在Future中之外,还必须将其配置为在单独的执行上下文中运行,该上下文已配置了足够的线程来处理预期的并发性。

该文档似乎在说ReactiveMongo是非阻塞的,因此您不必担心它会耗尽线程池中的许多线程。但是ReactiveMongo必须与某个地方的Mongo服务器通信

如何实现这种通信,以使Mongo不会用尽Play的默认线程池中的线程?

再一次,将非常感谢您链接到PlayReactiveMongoAkka等中的特定文件

弗拉基米尔·马特维耶夫(Vladimir Matveev)

是的,确实,您仍然需要使用线程来执行任何类型的工作,包括与数据库的通信。重要的是这种交流如何发生的。

ReactiveMongo在不使用阻塞I / O的意义上“不使用线程” 常见的Java I / O设施java.io.InputStream正在阻塞;这意味着从此类读取InputStream或写入将OutputStream阻塞线程,直到“另一侧”提供所需的数据或准备接受该数据为止。对于网络通信,这意味着线程被阻塞。

但是,Java提供了NIO API,该API支持非阻塞异步I / O。我现在不想详细介绍它,但是基本的想法自然是,非阻塞I / O不允许阻塞需要与外界交换一些数据的线程:例如,这些线程可以轮询数据源以检查是否有可用数据,如果没有,则它们返回线程池并可以用于其他任务。当然,这些功能是由底层操作系统提供的。

非阻塞I / O的确切实现细节通常隐藏在Netty之类的高级库中,因为它一点都不好用。例如,Netty(正是ReactiveMongo使用的库)提供了不错的异步回调类API,该API确实易于使用,但功能强大且表达能力强,可以构建具有高吞吐量的复杂I / O繁重的应用程序。

因此,ReactiveMongo使用Netty与Mongo数据库服务器进行通信,并且由于Netty是异步网络I / O的实现,因此ReactiveMongo确实不需要长时间阻塞线程。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章