强制Hikari / Hibernate关闭陈旧的(泄漏的)连接

时间:2018-09-20 12:59:41

标签: java spring hibernate filemaker hikaricp

我正在使用Hibernate 5.3和Hikari 2.7在Spring Boot 2中通过the official JDBC driver处理FileMaker 16数据源。

FileMaker Server性能很差,大表的SQL查询执行时间可能达到一分钟。当连接池中充满了永不释放的活动连接时,有时会导致连接泄漏。

问题是如何强制已挂在那里的池中的活动连接关闭两分钟,然后将它们移至空闲状态并可供再次使用。

作为示例,我正在使用findAll中的org.springframework.data.repository.PagingAndSortingRepository方法通过RestController访问FileMaker数据源:

@RestController
public class PatientController {

    @Autowired
    private PatientRepository repository;

    @GetMapping("/patients")
    public Page<Patient> find(Pageable pageable) {
        return repository.findAll(pageable);
    }
}

原始调用/patients几次导致连接泄漏,这是Hikari报告的内容:

  

2018-09-20 13:49:00.939调试1 --- [l-1管家]   com.zaxxer.hikari.pool.HikariPool:HikariPool-1-池统计   (总数= 10,活动= 10,空闲= 0,等待= 2)

它还会引发如下异常:

java.lang.Exception: Apparent connection leak detected
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128) ~[HikariCP-2.7.9.jar!/:na]

我需要的是,如果repository.findAll花费的时间超过N秒,则必须终止连接,并且控制器方法必须抛出异常。如何实现?

这是我的Hikari配置:

 allowPoolSuspension.............false
 autoCommit......................true
 catalog.........................none
 connectionInitSql...............none
 connectionTestQuery............."SELECT COUNT(*) FROM Clinics"
 connectionTimeout...............30000
 dataSource......................none
 dataSourceClassName.............none
 dataSourceJNDI..................none
 dataSourceProperties............{password=<masked>}
 driverClassName................."com.filemaker.jdbc.Driver"
 healthCheckProperties...........{}
 healthCheckRegistry.............none
 idleTimeout.....................600000
 initializationFailFast..........true
 initializationFailTimeout.......1
 isolateInternalQueries..........false
 jdbc4ConnectionTest.............false
 jdbcUrl.........................jdbc:filemaker://***:2399/ec_data
 leakDetectionThreshold..........90000
 maxLifetime.....................1800000
 maximumPoolSize.................10
 metricRegistry..................none
 metricsTrackerFactory...........none
 minimumIdle.....................10
 password........................<masked>
 poolName........................"HikariPool-1"
 readOnly........................false
 registerMbeans..................false
 scheduledExecutor...............none
 scheduledExecutorService........internal
 schema..........................none
 threadFactory...................internal
 transactionIsolation............default
 username........................"CHC"
 validationTimeout...............5000

2 个答案:

答案 0 :(得分:1)

HikariCP仅专注于连接池管理,以管理由其形成的连接。

loginTimeout-HikariCP等待与数据库建立连接的时间(基本上是JDBC连接)

spring.datasource.hikari.connectionTimeout=30000

maxLifetime-连接在关闭之前将在池中生存多长时间

spring.datasource.hikari.maxLifetime=1800000

idleTimeout-池中未使用的连接存在多长时间

spring.datasource.hikari.idleTimeout=30000

如果请求花费的时间超过定义的超时时间,请使用javax.persistence.query.timeout取消请求。

javax.persistence.query.timeout(长毫秒)

  

javax.persistence.query.timeout提示定义查询多长时间   允许在取消之前运行。 Hibernate无法处理此问题   本身超时,但通过JDBC将其提供给JDBC驱动程序   Statement.setTimeout方法。

答案 1 :(得分:0)

即使在javax.persistence.query.timeout设置程序的驱动程序实现中设置了超时值,filemaker JDBC驱动程序也会忽略java.sql.setQueryTimeout参数。因此,我通过扩展类com.filemaker.jdbc.Driver并覆盖了connect方法来解决了该问题,以便将sockettimeout参数添加到连接属性中。设置好此参数后,如果在超时时间内没有数据来自套接字,则FM JDBC驱动程序将中断连接。

我还向文件制作人提出了一个问题:https://community.filemaker.com/message/798471