scala - Play Framework 2.X 和阻塞数据库调用

标签 scala asynchronous playframework nonblocking playframework-2.3

我有点困惑。

来自 documentation :

Play default thread pool - This is the default thread pool in which all application code in Play Framework is executed, excluding some iteratees code. It is an Akka dispatcher, and can be configured by configuring Akka, described below. By default, it has one thread per processor.



将阻塞式数据库调用包装在 Future 中是否带来好处? ,调用Future本身被 async 包裹 Controller (返回它),为了让默认线程池 处理其他用户的请求?

它只会将阻塞代码移动到另一个线程中(来自专用的 ExecutionContext),但会留下 Action畅通。

我遇到了 this post但我对给出的答案不满意。
事实上,如果我让数据库在默认线程池中调用阻塞,它是否可能会同时阻止处理不依赖于数据库的其他用户请求?

注意:我的数据库 (Neo4j) 没有异步驱动程序。

最佳答案

有几种方法可以处理阻塞调用。我不能说哪个是最好的,因为它肯定取决于特定的用例,并且需要大量的基准测试。

默认情况下,Play 使用一个线程池处理请求,每个 cpu 核心一个线程。因此,例如,如果您在四核 CPU 上运行 Play 应用程序,那么如果它们使用对数据库的阻塞调用,它将只能处理 4 个并发请求。所以是的,所有其他传入请求都必须等到其中一个线程被释放。

最简单的解决方案是在默认线程池(在 application.conf 中)增加 Play 用于处理请求的线程数:

play {
   akka {
     akka.loggers = ["akka.event.slf4j.Slf4jLogger"]
     loglevel = WARNING
     actor {
        default-dispatcher = {
           fork-join-executor {
             parallelism-min = 300
             parallelism-max = 300
           }
        }
     }
   }
}

下一个选项是您在问题中提到的选项——将阻塞数据库调用卸载到另一个 ExecutionContext .您可以在 application.conf 中配置一个单独的线程池,如下所示:
database-io {
    fork-join-executor {
       parallelism-factor = 10.0
    }
}

这将在名为 database-io 的池中为每个 cpu 核心创建一个 10 个线程。 ,并且可以像这样在 Play 中访问:
val dbExecutor: ExecutionContext = Akka.system.dispatchers.lookup("database-io")

val something = Future(someBlockingCallToDb())(dbExecutor)

这将允许默认线程池在等待 Future 时处理更多请求。去完成。第三种选择是使用 Actor处理数据库调用,但这更复杂,超出了这个问题的范围。

底线是, ,使用更大的线程池或不同的 ExecutionContext用于阻止调用,就像您一样 从不 如果可以的话,希望阻塞在默认线程池中。

这一切都在 Play Documentation for Thread Pools 中进行了概述。 . (最新版本)

关于scala - Play Framework 2.X 和阻塞数据库调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24591905/

相关文章:

java - Play Framework 清洁与清洁所有

Scala 在正则表达式上直接匹配大小写

java - 将文件上传到 HDFS 或直接创建和写入 HDFS 文件哪个更快?

Python:按顺序发送异步http请求并自动处理cookie?

node.js - NodeJS,从async wait获取返回值

java - 为什么 jacoco :cover report 0 tests, 0 次失败,0 次错误用于 Play 2.2 中的测试?

scala - 使用 Dispatch 和 Scala 时如何打印 http 请求

scala - scala-错误: not found: value

javascript - 在 Nodejs 4.x 中从不同文件位置重用异步函数的有效方法是什么?

java - Nagle的算法是用Play框架/Netty开启还是关闭?