阅读有关 Play Framework 和 ReactiveMongo 的文档让我相信 ReactiveMongo 的工作方式是使用很少的线程并且从不阻塞。
但是,从 Play 应用程序到 Mongo 服务器的通信似乎必须在某个线程上发生。这是如何实施的?Play、ReactiveMongo、Akka 等的源代码链接也将不胜感激。
Play 框架在此页面上包含一些关于线程池的文档。它开始:
Play 框架自下而上是一个异步 Web 框架。使用迭代器异步处理流。Play 中的线程池被调整为使用比传统 Web 框架更少的线程,因为 play-core 中的 IO 永远不会阻塞。
然后谈了一点 ReactiveMongo:
典型的 Play 应用程序最常阻塞的地方是它与数据库通信时。不幸的是,没有一个主要数据库为 JVM 提供异步数据库驱动程序,因此对于大多数数据库,您唯一的选择是使用阻塞 IO。一个值得注意的例外是 ReactiveMongo,它是 MongoDB 的驱动程序,它使用 Play 的 Iteratee 库与 MongoDB 对话。
以下是关于使用 Futures 的说明:
请注意,您可能会因此将阻塞代码包装在 Futures 中。这并不意味着它是非阻塞的,它只是意味着阻塞将发生在不同的线程中。您仍然需要确保您正在使用的线程池有足够的线程来处理阻塞。
在页面处理异步结果的播放文档中有类似的注释:
您不能通过将同步 IO 包装在 Future 中神奇地将其转换为异步。如果您无法更改应用程序的体系结构以避免阻塞操作,那么在某些时候必须执行该操作,并且该线程将阻塞。因此,除了将操作封装在 Future 中之外,还需要将其配置为在单独的执行上下文中运行,该执行上下文已配置了足够的线程来处理预期的并发性。
文档似乎在说 ReactiveMongo 是非阻塞的,因此您不必担心它会占用线程池中的大量线程。但是 ReactiveMongo 必须在某处与 Mongo 服务器通信。
这种通信是如何实现的,以便 Mongo 不会用完 Play 的默认线程池中的线程?
再一次,非常感谢Play、ReactiveMongo、Akka等中特定文件的链接。