slickでHikariCPを使った時の設定値の上書きに関して
slickでHikariCPを使うときに、設定値が上書きされて コードを見てたら気づいたことがあったので残します。
slickでHikariCPを使うときの設定
HikariCP https://github.com/brettwooldridge/HikariCP
db.master { url = "jdbc:mysql://hoge:3306/hoge" driver=com.mysql.jdbc.Driver user = hoge password = hoge # connectionPoolはHikariCPを選択する部分 connectionPool = HikariCP keepAliveConnection = true properties = { #HikariCPの設定ファイルをここに記入する maximumPoolSize = 10 minimumIdle = 10 ...etc } }
こんな感じで設定してみたら、maximumPoolSize
とminimumIdle
が10になるので
動かすと、mysql側でshow processlist
を確認したら20プロセスあった。
それで、設定の部分のコードを見てみました。
コネクションプールの選択の部分
https://github.com/slick/slick/blob/3.1/slick/src/main/scala/slick/jdbc/JdbcDataSource.scala
28行目あたりが、コネクションプールの選択の部分ですね。 connectionPoolの部分を見て、設定をしています。
def forConfig(c: Config, driver: Driver, name: String, classLoader: ClassLoader): JdbcDataSource = { def loadFactory(name: String): JdbcDataSourceFactory = { val clazz = classLoader.loadClass(name) clazz.getField("MODULE$").get(clazz).asInstanceOf[JdbcDataSourceFactory] } val pf: JdbcDataSourceFactory = c.getStringOr("connectionPool", "HikariCP") match { case "disabled" => DataSourceJdbcDataSource case "HikariCP" => loadFactory("slick.jdbc.hikaricp.HikariCPJdbcDataSource$") case "slick.jdbc.HikariCPJdbcDataSource" => logger.warn("connectionPool class 'slick.jdbc.HikariCPJdbcDataSource$' has been renamed to 'slick.jdbc.hikaricp.HikariCPJdbcDataSource$'") loadFactory("slick.jdbc.hikaricp.HikariCPJdbcDataSource$") case name => loadFactory(name) } pf.forConfig(c, driver, name, classLoader) }
HikariCPの場合、slick.jdbc.hikaricp.HikariCPJdbcDataSource
を見ていることがわかります。
HikariCPの設定の上書き
// propertiesの設定を読み込む c.getPropertiesOpt("properties").foreach(hconf.setDataSourceProperties) // HikariCPの設定を読み込む hconf.setConnectionTimeout(c.getMillisecondsOr("connectionTimeout", 1000)) hconf.setValidationTimeout(c.getMillisecondsOr("validationTimeout", 1000)) hconf.setIdleTimeout(c.getMillisecondsOr("idleTimeout", 600000)) hconf.setMaxLifetime(c.getMillisecondsOr("maxLifetime", 1800000)) hconf.setLeakDetectionThreshold(c.getMillisecondsOr("leakDetectionThreshold", 0)) hconf.setInitializationFailFast(c.getBooleanOr("initializationFailFast", false)) c.getStringOpt("connectionTestQuery").foreach { s => hconf.setJdbc4ConnectionTest(false) hconf.setConnectionTestQuery(s) } c.getStringOpt("connectionInitSql").foreach(hconf.setConnectionInitSql) val numThreads = c.getIntOr("numThreads", 20) hconf.setMaximumPoolSize(c.getIntOr("maxConnections", numThreads * 5)) hconf.setMinimumIdle(c.getIntOr("minConnections", numThreads)) hconf.setPoolName(name) hconf.setRegisterMbeans(c.getBooleanOr("registerMbeans", false)) // Equivalent of ConnectionPreparer hconf.setReadOnly(c.getBooleanOr("readOnly", false)) c.getStringOpt("isolation").map("TRANSACTION_" + _).foreach(hconf.setTransactionIsolation) hconf.setCatalog(c.getStringOr("catalog", null))
初めに propertiesが呼ばれてそのまま設定され その後、デフォルトの設定が反映されるみたいです。
propertiesにmaximumPoolSizeを設定していても maxConnectionsが優先されるみたいです。 あと、HikariCP側と若干命名が変わっているです。
これが原因で、propertiesにmaximumPoolSizeとかを設定しても上書きされていました!!! なるほど。。。
# デフォルトの設定値 val numThreads = c.getIntOr("numThreads", 20) hconf.setMaximumPoolSize(c.getIntOr("maxConnections", numThreads * 5)) hconf.setMinimumIdle(c.getIntOr("minConnections", numThreads))
設定の例
db.master { url = "jdbc:mysql://hoge:3306/hoge" driver=com.mysql.jdbc.Driver user = hoge password = hoge connectionPool = HikariCP keepAliveConnection = true maxConnections = 10 minConnections = 10 connectionTimeout = 10000 validationTimeout = 5000 idleTimeout = 600000 maxLifetime = 3000000 leakDetectionThreshold = 0 initializationFailFast = false readOnly = false catalog = null properties = { autoCommit = true initializationFailFast = true isolateInternalQueries = false allowPoolSuspension = false } }
まとめ
propertiesに書いても、上書きされることを覚えておく!!