一定数量的查询后 HikariCP 连接超时错误

Posted

技术标签:

【中文标题】一定数量的查询后 HikariCP 连接超时错误【英文标题】:HikariCP connection timeout error after certain amount of queries 【发布时间】:2017-06-19 18:13:22 【问题描述】:

在开始之前,我想说我已经检查了以下内容,但他们没有帮助我:

HikariCP connection error HikariCP - connection is not available https://github.com/brettwooldridge/HikariCP/issues/104

基本上,我得到了 HikariCP stracktrace,但我不知道是什么原因造成的。

java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:548)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:186)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:145)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:83)
at de.arraying.Arraybot.managers.ManagerSync.addCustomCommand(ManagerSync.java:192)
at de.arraying.Arraybot.commands.CommandsCommand.onCommand(CommandsCommand.java:100)
at de.arraying.Arraybot.commands.Command.execute(Command.java:72)
at de.arraying.Arraybot.listeners.ListenerChat.onGuildMessageReceived(ListenerChat.java:68)
at net.dv8tion.jda.core.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:299)
at net.dv8tion.jda.core.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:64)
at net.dv8tion.jda.core.handle.MessageCreateHandler.handleDefaultMessage(MessageCreateHandler.java:97)
at net.dv8tion.jda.core.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:47)
at net.dv8tion.jda.core.handle.SocketHandler.handle(SocketHandler.java:38)
at net.dv8tion.jda.core.requests.WebSocketClient.handleEvent(WebSocketClient.java:688)
at net.dv8tion.jda.core.requests.WebSocketClient.onTextMessage(WebSocketClient.java:437)
at com.neovisionaries.ws.client.ListenerManager.callOnTextMessage(ListenerManager.java:352)
at com.neovisionaries.ws.client.ReadingThread.callOnTextMessage(ReadingThread.java:262)
at com.neovisionaries.ws.client.ReadingThread.callOnTextMessage(ReadingThread.java:240)
at com.neovisionaries.ws.client.ReadingThread.handleTextFrame(ReadingThread.java:965)
at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:748)
at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:110)
at com.neovisionaries.ws.client.ReadingThread.run(ReadingThread.java:66)

我尝试更改 maximum pool sizeminimum idle 并且还启用了 leak detection(在 2 秒时)。这些都没有帮助,除了我每次执行查询时都会进行泄漏检测,所以可能与此有关。

这是我当前的配置:

    HikariConfig hikariConfig = new HikariConfig();
    hikariConfig.setJdbcUrl("jdbc:mysql://"+url+":3306/"+database+"?useSSL=false");
    hikariConfig.setUsername(username);
    hikariConfig.setPassword(password);
    hikariConfig.setMaximumPoolSize(10);
    hikariConfig.setMinimumIdle(3);
    hikariConfig.setLeakDetectionThreshold(2000);
    dataSource = new HikariDataSource(hikariConfig);

我的查询方法结构如下:

        // inside a try/catch, after some checks that aren't related.
        PreparedStatement preparedStatement =
                dataSource.getConnection().prepareStatement(query);
        preparedStatement.setString(2, id);
        preparedStatement.setString(3, name);
        preparedStatement.setObject(1, value);
        preparedStatement.executeUpdate();
        preparedStatement.close();

我应该在此之后关闭连接吗?我能想象的唯一可能导致错误的是内存泄漏,我认为我没有。我的 CPU 使用率也很好,我的互联网连接也很好。除了在几次之后才开始抛出此错误之外,所有查询都可以正常工作。

【问题讨论】:

既然它说request timed out after 30000ms. 我会认为这是一个与网络相关的问题,或者你的数据库服务器没有更多的连接? @Redlab 我如何确认它没有更多的连接? 【参考方案1】:

“每次执行查询时都会进行泄漏检测”。

你当然是。在您的示例中,您从DataSource 中获得Connection,执行PreparedStatement,关闭PreparedStatement,然后不关闭Connection,因此它不会返回到池中并导致泄漏.

关闭你的人脉!只有你能防止fores...err,连接泄漏。

【讨论】:

好的,感谢您告诉我,我假设 CP 为我处理了打开和关闭连接。我想这就是为什么你不应该假设......现在要更新我的代码,看看它是否会改变...... 当您调用close() 时,连接并没有真正关闭,而是返回到池中(因为close() 被一些实现了一些池逻辑的HikariConnection 类覆盖)。 我已经执行了 20 多个查询,没有一个给我错误或内存泄漏警告,希望关闭连接可以解决这个问题。 哦,我可以保证。但这并不意味着没有其他问题。我的保证仅适用于未关闭的连接。

以上是关于一定数量的查询后 HikariCP 连接超时错误的主要内容,如果未能解决你的问题,请参考以下文章

如何设置远程连接到 postgresql 数据库的 jdbc 连接超时值?

HikariCP:为啥连接泄漏和释放导致新数据库连接的“连接尝试超时”?

HikariPool-1 - 连接不可用,请求超时

hikari为什么不需要配置连接池初始化大小

HikariCP - MYSQL 连接关闭后不允许操作。可能考虑使用更短的 maxLifetime 值

Spring Boot 2.1.4 + JDBI + HikariCP + PostgreSQL 发生错误后连接未释放到池