ill*_*out 14 scala reactive-programming playframework iterate reactivemongo
阅读有关Play Framework和ReactiveMongo的文档让我相信ReactiveMongo的工作方式是它使用很少的线程而且永远不会阻塞.
但是,似乎从Play应用程序到Mongo服务器的通信必须在某个某个线程上发生.这是如何实现的?Play,ReactiveMongo,Akka等源代码的链接也将非常受欢迎.
Play Framework在此页面上包含有关此主题的一些文档,内容涉及线程池.它开始:
Play框架是自下而上的异步Web框架.使用迭代器异步处理流.Play中的线程池被调整为使用比传统Web框架更少的线程,因为play-core中的IO永远不会阻塞.
然后谈谈ReactiveMongo:
典型Play应用程序阻止的最常见位置是它与数据库通信时.遗憾的是,没有一个主要数据库为JVM提供异步数据库驱动程序,因此对于大多数数据库,您唯一的选择是使用阻塞IO.一个值得注意的例外是ReactiveMongo,它是MongoDB的一个驱动程序,它使用Play的Iteratee库与MongoDB进行通信.
以下是关于使用期货的说明:
请注意,您可能想要将您的阻止代码包装在Futures中.这不会使它成为非阻塞,它只是意味着阻塞将在不同的线程中发生.您仍然需要确保您在那里使用的线程池有足够的线程来处理阻塞.
处理异步结果的页面上的Play文档中有类似的注释:
通过将同步IO包装在Future中,您无法神奇地将同步IO变为异步.如果您无法更改应用程序的体系结构以避免阻塞操作,那么在某些时候必须执行操作,并且该线程将阻塞.因此,除了将操作封装在Future中之外,还需要将其配置为在单独的执行上下文中运行,该上下文已配置有足够的线程来处理预期的并发性.
文档似乎说ReactiveMongo是非阻塞的,所以你不必担心它占用你线程池中的很多线程.但ReactiveMongo必须在某处与Mongo服务器通信.
如何实现这种通信,以便Mongo不会使用Play的默认线程池中的线程?
再次,非常感谢Play,ReactiveMongo,Akka等特定文件的链接.
Vla*_*eev 11
是的,确实,您仍然需要使用线程来执行任何类型的工作,包括与数据库的通信.重要的是这种沟通究竟是如何发生的.
ReactiveMongo在一定意义上"不使用线程",它不使用阻塞I/O.通常的Java I/O设施就像java.io.InputStream阻塞; 这意味着从这样的读取InputStream或写入OutputStream阻止线程,直到"另一方"提供所需的数据或准备接受它.对于网络通信,这意味着线程将被阻止.
但是,Java提供了支持非阻塞和异步 I/O的NIO API.我现在不想深入了解其细节,但基本思路当然是非阻塞I/O允许不阻止需要与外界交换某些数据的线程:例如,这些线程可以轮询数据源以检查是否有可用的数据,如果没有,则返回到线程池并可用于其他任务.当然,在那里,这些设施由底层操作系统提供.
非阻塞I/O的确切实现细节通常隐藏在Netty等高级库中,因为它使用起来并不好.例如,Netty(正是ReactiveMongo使用的库)提供了很好的异步回调式API,它非常易于使用,但功能强大且足够强大,可以构建具有高吞吐量的复杂I/O密集型应用程序.
因此,ReactiveMongo使用Netty与Mongo数据库服务器通信,并且由于Netty是异步网络I/O的实现,ReactiveMongo实际上不需要长时间阻塞线程.
| 归档时间: |
|
| 查看次数: |
1439 次 |
| 最近记录: |