scala – Play Framework 2.X和阻止数据库调用
我有点困惑.
从documentation:
它是否有利于在Future中包装阻塞数据库调用,对Future的调用本身由异步控制器包装(返回它),以便让默认线程池处理其他用户请求? 它只会将阻塞代码移动到另一个线程(来自专用的ExecutionContext)中,但保持Action不受阻挡. 我遇到了this post,但我对给定的答案不满意. 注意:我的数据库(Neo4j)没有异步驱动程序. 解决方法
有几种方法可以处理阻塞调用.我不能说哪个最好,因为它肯定取决于具体的用例,并且需要大量的基准测试.
默认情况下,Play使用每个cpu核心一个线程的线程池处理请求.因此,例如,如果您在四核CPU上运行Play应用程序,它将只能处理4个并发请求,如果它们正在使用对数据库的阻塞调用.所以是的,所有其他传入的请求都必须等到其中一个线程被释放. 最简单的解决方案是增加Play用于处理默认线程池(在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中配置一个单独的线程池,如下所示: 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中概述.(最新版本) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |