我使用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完成连接就应该返回连接。
答案 0 :(得分:1)
对于遇到同一问题的下一个人:
将removeAbandonedTimeout调整为非常小的值(@cloudwalker使用10秒)并查看行为是否有所改善。
答案 1 :(得分:1)
我使用了一个小的removeAbandonedTimeout值和一个logAbandoned = true的组合来调试这个问题,发现它来自某些人最近添加的代码,它运行的是纯JDBC查询而没有关闭连接。 logAbandoned向我展示了堆栈跟踪,这导致了我的违规代码。