使用Tomcat数据库池和Oracle进行Spring引导,而不是及时重新连接到池的连接

时间:2018-01-22 20:14:27

标签: spring oracle tomcat spring-orm tomcat-dbcp

我使用Spring Boot with Oracle和Tomcat DB Pool。我遇到了很长一段时间将连接返回到池中的问题。我的最大活动数为500,非常大,仅用于测试目的,我使用JMeter运行一些负载测试。测试执行后,我查看数据源池指标,它看起来像这样:

  "datasource.myDataSource.active": 120,
  "datasource.myDataSource.usage": 0.24

此时,不再发生数据库活动。但是,如果我在大约5分钟后检查,我仍然具有完全相同数量的活动连接,因此如果我运行另一个测试,那么活动连接的数量将加倍。如果我离开它大约10-15分钟左右,最终连接将返回到池中。但是,这意味着如果有很多人同时使用该应用程序,我们会很快耗尽连接,并且由于它们很长时间没有返回池中,我们最终会超时。

这是我的数据源配置:

 @Bean(name = "myDataSource")
    @ConfigurationProperties(prefix = "datasource.myDataSource")
    public DataSource userStoreDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "myDataSourceEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean myDataSourceEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("myDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.mypackage..model.entity")
                .persistenceUnit("someStuff")
                .build();
    }

    @Bean(name = "myDataSourceTransactionManager")
    public PlatformTransactionManager myDataSourceTransactionManager(
            @Qualifier("myDataSourceEntityManagerFactory") EntityManagerFactory
                    myDataSourceManagerFactory) {
        return new JpaTransactionManager(myDataSourceEntityManagerFactory);
    }

'datasource.myDataSource.driver-class-name','oracle.jdbc.OracleDriver'
'datasource.myDataSource.maxActive','500'
'datasource.myDataSource.removeAbandoned','true'
'datasource.myDataSource.removeAbandonedTimeout','500'
'datasource.myDataSource.test-on-borrow','true'
'datasource.myDataSource.test-while-idle','true'
'datasource.myDataSource.validation-query','SELECT 1 FROM DUAL'

我错过了一些关键的配置文件吗?我会认为一旦Spring完成连接就应该返回连接。

2 个答案:

答案 0 :(得分:1)

对于遇到同一问题的下一个人:

将removeAbandonedTimeout调整为非常小的值(@cloudwalker使用10秒)并查看行为是否有所改善。

答案 1 :(得分:1)

我使用了一个小的removeAbandonedTimeout值和一个logAbandoned = true的组合来调试这个问题,发现它来自某些人最近添加的代码,它运行的是纯JDBC查询而没有关闭连接。 logAbandoned向我展示了堆栈跟踪,这导致了我的违规代码。