Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Tomcat/Spring连接池-列出连接项_Java_Spring_Tomcat - Fatal编程技术网

Java Tomcat/Spring连接池-列出连接项

Java Tomcat/Spring连接池-列出连接项,java,spring,tomcat,Java,Spring,Tomcat,正在尝试调试与问题类似的应用程序。我目前正在使用: Tomcat 6.0.32-公司要求 Tomcat JDBC池1.0.9.3 Java 1.6.x-公司的要求 春季3.2.14 myBatis 3.2.8 石英2.2.2 SpringWeb请求和石英触发的作业混合使用池。运行大约5次后,池中没有更多可用的连接,initialSize=5,maxActive=10。增加maxActive没有任何作用,只是需要更长的时间和更多的Quartz运行,池才会变空 2016-05-19 08:59:

正在尝试调试与问题类似的应用程序。我目前正在使用:

  • Tomcat 6.0.32-公司要求
  • Tomcat JDBC池1.0.9.3
  • Java 1.6.x-公司的要求
  • 春季3.2.14
  • myBatis 3.2.8
  • 石英2.2.2
SpringWeb请求和石英触发的作业混合使用池。运行大约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
到目前为止我所做的:

  • 从Apache Commons DBCP切换到Tomcat JDBC池。这是有效的
  • 已打开Tomcat JDBC池的调试。也在工作
  • 在Tomcat上启用JMX来使用jvisualvm监视连接池-这不起作用,因为Spring实际上是在创建连接池,而不是Tomcat
打开Tomcat JDBC池的调试后,日志记录不会显示未释放连接的位置/原因。对于JMX路由,因为我没有使用Spring引导,所以我似乎无法在Spring中启用JMX来查看连接池

我的问题是,有没有一种方法可以从Spring(而不是Tomcat)获取Spring连接池对象/实例,然后对所有连接进行迭代,并列出每个连接上的一些简单属性,如活动、正在使用、已关闭等

我的想法是,我只是编写一些Java代码,在Quartz作业前后将连接池列表转储到日志中。转储我在Web应用程序中执行的关键SpringWeb事务的列表

我的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>

这“似乎”起作用了,不确定是否有更好的方法:

  • 在春天制作了一个ApplicationContextAware Bean
  • 将ApplicationContextAware Bean连接到Quartz类
  • 在石英类中,我:
    • 使用ApplicationContextAware Bean获取连接池
    • 使用for循环迭代所有连接并转储属性
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 : -----------------------------------------------------------------------------------------------------------------
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 : -----------------------------------------------------------------------------------------------------------------
Quartz运行后的dumpConnectionPool()显示4个空闲,1个活动:

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 : -----------------------------------------------------------------------------------------------------------------
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 : -----------------------------------------------------------------------------------------------------------------