尝试调试与Missing connections in tomcat jdbc connection pool具有类似问题的应用程序。我目前正在使用:
Spring Web请求以及使用Pool的Quartz触发作业混合在一起。大约5次运行后,我在池中没有更多可用连接,initialSize = 5,maxActive = 10。增加maxActive什么都不做,它只需要更长的时间,并且在池为空之前运行更多的Quartz。
2016-05-19 08:59:46,027 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread QuartzSchedulerThread.run 276 : batch acquisition of 1 triggers
2016-05-19 09:00:00,001 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread QuartzSchedulerThread.run 276 : batch acquisition of 0 triggers
2016-05-19 09:00:00,003 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6 JobRunShell.run 201 : Calling execute on job DEFAULT.refMigrDetail
2016-05-19 09:00:00,003 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6 DataSourceUtils.doGetConnection 110 : Fetching JDBC Connection from DataSource
2016-05-19 09:00:24,409 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread QuartzSchedulerThread.run 276 : batch acquisition of 0 triggers
2016-05-19 09:00:30,004 ERROR org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6 CMRoreReferenceMigrator.run 93 : org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6] Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[10 in use].
2016-05-19 09:00:49,378 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread QuartzSchedulerThread.run 276 : batch acquisition of 0 triggers
到目前为止我做了什么:
在为Tomcat JDBC Pool启用DEBUG时,日志记录不会显示未释放连接的位置/原因。对于JMX路由,由于我没有使用Spring-Boot,我似乎无法在Spring中启用JMX来查看连接池。
我的问题是,有没有办法从SPRING(而不是Tomcat)中获取Spring Connection Pool对象/实例,然后通过它迭代所有连接,并列出每个连接上的一些简单属性,如活动,正在使用,关闭等...
我的想法是我只写了一些Java代码,它将连接池列表转储到Quartz作业之前和之后的日志中。转发我在Web应用程序之前和之后运行的关键Spring Web事务列表。
My Spring连接池配置,DB2数据库:
<bean id="rrfecfDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="${rrfecf.datasource.jdbcDriver}" />
<property name="url" value="${rrfecf.dataousrce.databaseUrl}" />
<property name="username" value="${rrfecf.datasource.username}" />
<property name="password" value="${password:rrfecf.datasource}" />
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
<property name="defaultAutoCommit" value="false" />
<property name="maxIdle" value="5" />
<property name="minIdle" value="0" />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="validationQuery" value="SELECT CURRENT_DATE FROM sysibm.sysdummy1" />
<property name="timeBetweenEvictionRunsMillis" value="600000" /> <!-- 10 minutes -->
<property name="minEvictableIdleTimeMillis" value="900000" /> <!-- 15 minutes -->
</bean>
myBatis Spring配置:
<bean id="rrfecfSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="WEB-INF/sqlMapConfig.xml"/>
<property name="dataSource" ref="rrfecfDataSource" />
</bean>
答案 0 :(得分:-1)
这似乎“有效”,不确定是否有更好的方法:
ApplicationContextAware类:
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* <p>
* The <code>BatchApplicationContextProvider</code> provides...
* </p>
*/
public class BatchApplicationContextProvider implements ApplicationContextAware {
public static final String ID = BatchApplicationContextProvider.class.getName ();
private String SHORT_NAME = "BatchApplicationContextProvider()";
@SuppressWarnings("unused")
private String SYSTEM_IDENTITY = String.valueOf ( System.identityHashCode ( this ) );
private ApplicationContext context;
/**
*
*/
public BatchApplicationContextProvider() {
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
this.context = arg0;
}
public ApplicationContext getApplicationContext() {
return context;
}
public org.apache.tomcat.jdbc.pool.DataSource getConnectionPool () {
return ( DataSource ) this.context.getBean ( "rrfecfDataSource" );
}
}
样本用法:
public void dumpConnectionPool () {
org.apache.tomcat.jdbc.pool.DataSource lthePool = null;
ConnectionPool lbusyPool = null;
try {
lthePool = getBatchContext ().getConnectionPool ();
lbusyPool = lthePool.getPool ();
if ( lbusyPool != null ) {
if ( lbusyPool.getSize () > 0 ) {
getLog().info ( SHORT_NAME + ".run() - ConnectionPool - size....................[" + lbusyPool.getSize () + "] idle [" + lbusyPool.getIdle () + "] active [" + lbusyPool.getActive () + "]" );
//getLog().info ( SHORT_NAME + ".run() - ConnectionPool - idle....................[" + lbusyPool.getIdle () + "]" );
//getLog().info ( SHORT_NAME + ".run() - ConnectionPool - active..................[" + lbusyPool.getActive () + "]" );
//PoolConfiguration lpoolCfg = lbusyPool.getPoolProperties ();
}
}
lbusyPool = null;
lthePool = null;
}
catch ( Exception ltheXcp ) {
log.error ( ltheXcp );
}
finally {
}
}
我希望有人有一种更优雅的方式......这对我来说似乎是一种蛮力,但我现在需要在Web应用程序中解决这个问题。
编辑: dumpConnectionPool()存在问题... for循环似乎在迭代时挂起到所有连接,使它们全部“活动”。正在努力......
编辑: 取出for循环...设置connection = null似乎不会将其释放回连接池。
成功:
虽然不漂亮,但dumpConnectionPool()显示问题清单本身:
Quartz运行之前的dumpConnectionPool()显示5空闲,0活动:
2016-05-20 11:20:00,078 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.run 138 : -----------------------------------------------------------------------------------------------------------------
2016-05-20 11:20:00,078 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.dumpConnectionPool 257 : RunReferenceMigrator().run() - ConnectionPool - size....................[5] idle [5] active [0]
2016-05-20 11:20:00,078 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.run 140 : -----------------------------------------------------------------------------------------------------------------
dumpConnectionPool()在Quartz运行之后,显示4个空闲,1个活动:
2016-05-20 11:24:45,063 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.run 161 : -----------------------------------------------------------------------------------------------------------------
2016-05-20 11:24:45,063 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.dumpConnectionPool 257 : RunReferenceMigrator().run() - ConnectionPool - size....................[5] idle [4] active [1]
2016-05-20 11:24:45,063 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.run 163 : -----------------------------------------------------------------------------------------------------------------