【问题标题】:Best practice for Slick 2.1 / 3 execution context usageSlick 2.1 / 3 执行上下文使用的最佳实践
【发布时间】:2016-02-19 16:27:33
【问题描述】:

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

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

【问题讨论】:

    标签: multithreading scala slick spray slick-3.0


    【解决方案1】:

    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”用于 IO。因为默认的 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

    【讨论】:

    • 使用 fork-join 线程池确实不是一个好主意,但我如何确保 HTTP API DB 调用始终优先于使用 slick 3.0 的后台作业,因为使用了相同的执行上下文?
    • 我无法准确理解您的问题。为此,您需要向我展示一些代码。如果你想使用 scala 默认的 ExecutionContext ,就可以了。
    • 你需要在默认线程池中增加noOfThread。默认是 x1.means noOfThread =(number if processor) * 1. 你可以设置 1) scala.concurrent.context.minThreads 2)scala.concurrent.context.numThreads 3)scala.concurrent.context.maxThreads 更多详情见:stackoverflow.com/questions/14207762/…github.com/scala/scala/blob/2.11.x/src/library/scala/concurrent/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多