如何在不频繁重置连接的情况下使用HikariCP连接QuestDB?
解决HikariCP连接QuestDB时连接被自动关闭的问题
问题场景
使用PostgreSQL JDBC驱动配合HikariCP连接QuestDB,查询功能正常,但QuestDB日志显示所有池化连接会在59秒后被主动关闭,需要配置HikariCP让池化连接保持打开,仅驱逐已关闭或无效的连接。
代码实现
public static void main(String[] args) { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:postgresql://localhost:8812/qdb"); config.setUsername("admin"); config.setPassword("quest"); config.setMaxLifetime(60000); config.setMaximumPoolSize(10); // Create the DataSource HikariDataSource dataSource = new HikariDataSource(config); while (true) { // Use the DataSource to get a connection try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT now()")) { // Process the result while (resultSet.next()) { System.out.println(resultSet.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } Os.sleep(10000); } }
依赖配置
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.7.3</version> </dependency>
QuestDB日志片段
2024-09-24T11:09:26.276729Z I pg-server connected [ip=127.0.0.1, fd=2241972929959] ... 2024-09-24T11:10:24.950787Z I pg-server scheduling disconnect [fd=2241972929959, reason=15] 2024-09-24T11:10:24.951148Z I pg-server disconnected [ip=127.0.0.1, fd=2241972929959, src=queue]
解决方案
1. 调整QuestDB的连接超时配置
QuestDB默认的PostgreSQL兼容连接超时(pg.net.timeout)为60秒,这是连接被主动关闭的核心原因。修改QuestDB的server.conf配置文件,增大超时时间:
pg.net.timeout=300000
此处设置为5分钟(300000毫秒),可根据业务需求调整为更大的值。
2. 优化HikariCP参数配置
调整HikariCP参数,使其与QuestDB的超时配置匹配,并保持连接活跃:
public static void main(String[] args) { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:postgresql://localhost:8812/qdb"); config.setUsername("admin"); config.setPassword("quest"); // 设为比QuestDB超时小10秒,避免QuestDB先关闭连接 config.setMaxLifetime(290000); config.setMaximumPoolSize(10); // 每隔1分钟发送心跳,保持连接活跃 config.setKeepaliveTime(60000); // 借用连接时验证有效性的查询语句 config.setConnectionTestQuery("SELECT 1"); // 连接验证超时时间 config.setValidationTimeout(5000); // 保持最小空闲连接数,避免频繁创建销毁连接 config.setMinimumIdle(10); HikariDataSource dataSource = new HikariDataSource(config); while (true) { try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT now()")) { while (resultSet.next()) { System.out.println(resultSet.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } Os.sleep(10000); } }
关键参数说明:
maxLifetime:必须小于QuestDB的pg.net.timeout,确保HikariCP在连接被QuestDB关闭前主动回收,避免无效连接留在池中。keepaliveTime:定期向QuestDB发送心跳请求,防止连接被判定为空闲超时。connectionTestQuery:每次借用连接时执行简单查询,验证连接有效性,无效则自动驱逐并创建新连接。minimumIdle:设置与maximumPoolSize相同的值,保持池内始终有足够空闲连接,减少连接创建开销。
3. 验证效果
修改配置后重启QuestDB和应用,观察QuestDB日志,连接不会再被频繁关闭;应用可稳定复用池内连接,仅在连接无效时才会被驱逐重建。
内容的提问来源于stack exchange,提问作者Nick The Greek
相关产品推荐
相关产品推荐

