web-dev-qa-db-ja.com

Slick / HikariCPで接続が閉じられた後、操作は許可されません

Slick3.1.1 + HikariCP2.5.1を使用しています。私の設定は:

rdsConfig = {
  url = "jdbc:mysql://mydb.........us-west-2.rds.amazonaws.com:3306/owlschema"  

  driver = "com.mysql.jdbc.Driver"
  connectionPool = HikariCP
  maxConnections = 222   
  minConnections = 30
  keepAliveConnection = true
  properties = {
    user = "me"
    password = "mydarksecret"
  }
  numThreads = 40    
}

3秒あたり約1つのクエリを実行しており、各クエリの所要時間は0.4秒未満です。最初はすべて正常に動作しますが、約2時間後、HikariCPは接続を閉じ始め、「接続が閉じられた後は操作が許可されません」というエラーが発生します。

15:20:38.288 DEBUG [] [rdsConfig-8] com.zaxxer.hikari.pool.HikariPool - rdsConfig - Timeout failure stats (total=30, active=0, idle=30, waiting=0)
15:20:38.290 DEBUG [] [rdsConfig connection closer] com.zaxxer.hikari.pool.PoolBase - rdsConfig - Closing connection com.mysql.jdbc.JDBC4Connection@229960c: (connection is evicted or dead)
15:20:38.333 DEBUG [] [rdsConfig connection closer] com.zaxxer.hikari.pool.PoolBase - rdsConfig - Closing connection com.mysql.jdbc.JDBC4Connection@229960c failed
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at Sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_77]
    at Sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[na:1.8.0_77]
    at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[na:1.8.0_77]
    at Java.lang.reflect.Constructor.newInstance(Unknown Source) ~[na:1.8.0_77]

これを回避するために必要な他の構成設定はありますか? HikariCPが接続を閉じている理由がまったくわかりません。必要に応じて、閉じていない接続をコードに提供するだけではいけませんか?デフォルト設定でうまく動作するという評判があるので、なぜ問題が発生するのか混乱しています。ありがとう。

9
thund

HikariCPは、接続が切断されている、つまり(connection is evicted or dead)であると判断したため、接続を閉じようとしました。その後、運転手は「接続はすでに閉じられています」と言いましたが、これは予想外ではありません。

「なぜ接続が切れているのを閉じる必要があるのですか?」まあ、一時的に利用できなかった(または遅い)ため、検証テストは失敗しましたが、接続はドライバーの観点からはまだ「生きている」。ドライバーがリソースをクリーンアップする機会を与えるには、閉じるか、少なくとも試行することが不可欠です。

HikariCPは、次の5つの場合に接続を閉じます。

  1. 接続の検証に失敗しました。これはアプリケーションからは見えません。接続は廃止され、置き換えられます。 Failed to validate connection...の効果に関するログメッセージが表示されます。
  2. 接続がidleTimeoutより長くアイドル状態でした。これはアプリケーションからは見えません。接続は廃止され、置き換えられます。 (connection has passed idleTimeout)の閉鎖理由が表示されます。
  3. 接続がmaxLifetimeに到達しました。これはアプリケーションからは見えません。接続は廃止され、置き換えられます。 (connection has passed maxLifetime)の閉鎖理由が表示されます。または、maxLifetimeに到達したときに接続が使用されている場合は、後で(connection is evicted or dead)が表示されます。
  4. ユーザーが手動で接続を削除しました。これはアプリケーションからは見えません。接続は廃止され、置き換えられます。 (connection evicted by user)の閉鎖理由が表示されます。
  5. JDBC呼び出しがunrecoverableSQLExceptionをスローしましたこれはアプリケーションに表示されるはずです。 (connection is broken)の閉鎖理由が表示されます。

ここにはかなりの数の変数があります。ユーザー指定の設定に加えて、SlickによってどのHikariCPデフォルト設定が変更される可能性があるのか​​わかりません。周囲のログが表示されないため、他に関連する問題があるかどうかはわかりません。構成に222の接続が表示されているという事実には奇妙な点がありますが、タイムアウトの失敗時にログに記録されるプールの統計は(total=30, active=0, idle=30, waiting=0)であるため、RDSが上限を設定している可能性があります(?)。

問題を開くことをお勧めします Github上 、起動時にプール設定を含むログメッセージを添付し、例外の前の1分間ログのセクションを添付し、その他の関連する警告についてログファイルをgrepします。

9
brettw