Slick 2.1 / 3执行上下文使用的最佳实践

时间:2016-02-19 16:27:33

标签: multithreading scala slick spray slick-3.0

我们使用Slick(2.1.0)和Spray-io(1.3.3)。目前我们面临一个问题,因为我们对Spray HTTP API部分和访问同一数据库的后台运行作业使用相同的执行上下文。所有数据库/阻塞调用都使用相同的scala.concurrent.ExecutionContext.global执行上下文包装在期货中。

当后台作业开始繁重工作时,他们将消耗所有可用线程,这将导致API端超时,因为他们没有任何可用的线程来处理API工作。 显而易见的解决方案是对两个部分使用不同的执行上下文,总线程数不高于配置的数据库连接池(HikariCP)。 (这里部分建议https://www.playframework.com/documentation/2.1.0/ThreadPools#Many-specific-thread-pools)但是这样的设置如何与Slick 3一起工作,其中执行上下文与数据库配置本身联系在一起?

1 个答案:

答案 0 :(得分:2)

Slick3带有自己的执行上下文,线程数可配置。您可以调整所有连接池设置,例如(MySQL):

dev-dbconf={
dataSourceClass  =  "com.mysql.jdbc.jdbc2.optional.MysqlDataSource"
numThreads       =  10 //for execution context 
maxConnections   =  10
minConnections   =  5
connectionTimeout = 10000
initializationFailFast = false
properties {
    user         = "root"
    password     = "root"
    databaseName = "db_name"
    serverName   = "localhost"
}

}

在此配置中,您可以根据需要更改线程数。 我想建议你从来没有使用过“scala.concurrent.ExecutionContext.global”。因为默认的ExecutionContext带有fork-join线程池,这对IO不好。你可以为IO创建自己的线程池:

import scala.concurrent.ExecutionContext
import java.util.concurrent.Executors

object MyExecutionContext {

    private val concorrency = Runtime.getRuntime.availableProcessors()
    private val factor =  3 // get from configuration  file
    private val noOfThread = concorrency * factor
    implicit val ioThreadPool: ExecutionContext = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(noOfThread))

}
  // Use this execution context for IO instead of scala execution context.
 import MyExecutionContext.ioThreadPool

 Future{
 // your blocking IO code
 }

您可以根据自己的要求更改noOfThread。如果您根据机器中的数字处理器设置线程数,那将是一件好事。

有关详细信息,您可以看到Best Practices for Using Slick on ProductionSlick Doc