Play Framework 2.X 和阻塞数据库调用 [英] Play Framework 2.X and blocking database call

查看:23
本文介绍了Play Framework 2.X 和阻塞数据库调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点困惑.

来自文档:

播放默认线程池 - 这是默认线程池,其中Play Framework 中的所有应用程序代码都被执行,不包括一些迭代代码.它是一个 Akka 调度器,可以通过以下方式配置配置 Akka,如下所述.默认情况下,每个线程有一个线程处理器.

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 控制器包装(返回),为了让默认线程池处理其他用户的请求?

Does it bring benefit to wrap a blocking database call in a Future, the call to the Future being itself wrapped by an async controller (returning it), in order to let the default thread pool handling other users requests?

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

It would just move the blocking code inside another thread (from a dedicated ExecutionContext), but leave the Action unblocked.

我看到了这篇文章但我对给出的答案不满意.
确实,如果我让数据库调用在默认线程池中阻塞,它不会同时阻止处理不依赖于数据库的其他用户请求吗?

I came across this post but I'm not satisfied with the given answer.
Indeed, if I let the database call blocking within the default thread pool, wouldn't it potentially prevent handling other users requests that does not depend on database in the meantime?

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

Note: My database (Neo4j) hasn't an async driver.

推荐答案

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

There are a few ways to handle blocking calls. I can't say which is best, as it would most certainly depend on specific use cases, and require a ton of benchmarking.

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

By default, Play handles requests using a thread pool with one thread per cpu core. So, if you're running your Play app on a quad-core cpu, for example, it will only be able to handle 4 concurrent requests if they're using blocking calls to the database. So yes, all other incoming requests will have to wait until one of the threads had been freed up.

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

The simplest solution is to increase the number of threads Play uses to process requests in the default thread pool (in application.conf):

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 中配置一个单独的线程池,如下所示:

The next option is the one you mention in your question--offloading blocking database calls to another ExecutionContext. You can configure a separate thread pool within application.conf like so:

database-io {
    fork-join-executor {
       parallelism-factor = 10.0
    }
}

这将在名为 database-io 的池中为每个 cpu 核心创建一个 10 个线程,并且可以像这样在 Play 中访问:

This will create a 10 threads per cpu core in the pool called database-io, and can be accessed within Play like so:

val dbExecutor: ExecutionContext = Akka.system.dispatchers.lookup("database-io")

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

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

This will allow the default thread pool to handle more requests while it's waiting for the Future to complete. A third option would be to use an Actor to handle the database calls, but that's more complicated and beyond the scope of this question.

最重要的是,,使用更大的线程池或不同的 ExecutionContext 来阻塞调用,因为您永远不想阻塞如果可以的话,在默认线程池中.

The bottom line is, yes, use a larger thread pool or a different ExecutionContext for blocking calls, as you never want to block in the default thread pool if you can help it.

这在线程池的播放文档中都有概述.(最新版本)

This is all outlined in the Play Documentation for Thread Pools. (latest version)

这篇关于Play Framework 2.X 和阻塞数据库调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆