在Slick / HikariCP中连接关闭错误后,不允许任何操作

时间:2016-12-07 02:20:00

标签: mysql slick hikaricp aws-rds

我正在使用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秒运行一次查询,每次查询都是< 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完全关闭连接,如果它想要,它不应该只提供我的代码与非关闭连接?它以其默认设置运行良好而闻名,所以我很困惑为什么它有问题。感谢。

1 个答案:

答案 0 :(得分:6)

HikariCP确定连接已死,即(connection is evicted or dead),因此尝试关闭它。然后司机说,“抱歉连接已经关闭”,这并不意外。

你可能会想,“为什么你需要关闭一个死连接?”好吧,也许它只是暂时不可用(或慢)所以验证测试失败,但连接仍然是“从驱动程序的角度看“活着”。关闭或至少尝试,对于让驾驶员有机会清理资源至关重要。

HikariCP在五种情况下关闭了连接:

  1. 验证连接失败。这对您的应用程序是不可见的。连接已退役并已更换。您会看到Failed to validate connection...
  2. 效果的日志消息
  3. 连接空闲时间超过idleTimeout这对您的应用程序是不可见的。连接已退役并已更换。您会看到(connection has passed idleTimeout)的结果原因。
  4. 连接已达到maxLifetime这对您的应用程序是不可见的。连接已退役并已更换。您会看到(connection has passed maxLifetime)的关闭原因,或者如果在到达maxLifetime时连接正在使用,您将在以后看到(connection is evicted or dead)
  5. 用户手动逐出连接。这对您的应用程序是不可见的。连接已退役并已更换。您会看到(connection evicted by user)的结果原因。
  6. JDBC调用抛出了不可恢复的 SQLException这应该对您的应用程序可见。您会看到(connection is broken)的结果原因。
  7. 这里有很多变数。除了用户指定的设置外,我不知道Slick可能会更改HikariCP默认设置。您没有显示周围的日志,所以我无法判断是否有任何其他相关问题。您的配置显示222个连接这一事实很奇怪,但超时失败时记录的池统计信息为(total=30, active=0, idle=30, waiting=0),因此看起来RDS可能会限制您(?)。

    我建议打开问题on Github,在启动时附加包含池设置的日志消息,附加异常前一分钟的日志部分,并在日志文件中搜索任何其他相关警告。 / p>