【问题标题】:No operations allowed after connection closed errors in Slick/HikariCPSlick/HikariCP 中的连接关闭错误后不允许操作
【发布时间】:2016-12-07 02:20:00
【问题描述】:

我正在使用 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 个查询,每个查询耗时

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 完全关闭连接,如果它愿意,它不应该只为我的代码提供非关闭连接吗?它以其默认设置运行良好而享有盛誉,因此我对为什么会出现问题感到困惑。谢谢。

【问题讨论】:

    标签: mysql slick hikaricp aws-rds


    【解决方案1】:

    HikariCP 确定连接已死,即(connection is evicted or dead),因此试图关闭它。司机接着说,“对不起,连接已经关闭了”,这并不意外。

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

    HikariCP 关闭连接的五种情况:

    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 调用引发不可恢复 SQLException这应该对您的应用程序可见。您会看到 (connection is broken) 的关闭原因。

    这里有很多变量。除了用户指定的设置外,我不知道 Slick 可能会更改哪些 HikariCP 默认设置。您不显示周围的日志,所以我无法判断是否有任何其他相关问题。奇怪的是,您的配置显示 222 个连接,但在 Timeout Failure 中记录的池统计信息是 (total=30, active=0, idle=30, waiting=0),因此 RDS 似乎限制了您(?)。

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

    【讨论】:

    • 非常感谢您提供的详细信息。在您的 5 个关闭原因中,我收到了 ...passed idleTimeout...passed maxLifetime...evicted or dead。每个错误都遵循上面我的日志中显示的模式,即很快我得到closing connection (evicted or dead),然后是closing connection failed,然后是no operations allowed。我的配置文件还包含minConnections=30,因为我现在已经编辑了要显示的问题。那么当我的连接到达maxLifetime 时,HikariCP 是否会关闭我的连接,即使它们正在使用中?
    • HikariCP 在使用时不会关闭连接。如果一个正在使用的连接到达maxLifetime,它会标记为驱逐,并且会在下次线程尝试借用它时被驱逐。
    猜你喜欢
    • 1970-01-01
    • 2020-04-05
    • 2012-06-06
    • 2020-04-17
    • 2011-11-25
    • 2015-02-16
    • 2012-10-02
    • 2013-12-21
    • 2014-11-11
    相关资源
    最近更新 更多