当前位置: 首页 > 知识库问答 >
问题:

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

贾俊喆
2023-03-14
    null

Spring Web请求和Quartz触发的作业混合使用了这个池。运行大约5次后,池中没有可用的连接,initialsize=5,maxactive=10。增加maxActive没有什么作用,它只是在池空之前需要更长的时间和更多的石英运行。

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。
<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>
<bean id="rrfecfSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="configLocation" value="WEB-INF/sqlMapConfig.xml"/>
    <property name="dataSource" ref="rrfecfDataSource" />
</bean>

共有1个答案

谷梁云瀚
2023-03-14

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

  • 在Spring中创建了一个ApplicationContextAware Bean。
  • 将ApplicationContextAware Bean连接到Quartz类。
  • 在石英类中,我是:
    • 使用ApplicationContextAware Bean获取ConnectionPool。
    • 使用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 { 
    
        }
    
    
    }
    

    EDIT:取出for循环...设置connection=null并没有将其释放回连接池。

    成功:

    dumpConnectionPool()虽然不漂亮,但它本身显示了问题清单:

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

 类似资料:
  • null 如果我理解正确的话,我们应该在启动时有1个空闲连接,根据负载从0到3,对吗? 正在发生的情况是:启动时1个连接,如果负载较低,最多3个空闲连接,高负载后超过3个空闲连接。然后这些连接不会立即关闭,我们不知道它们何时/是否会关闭(有时它们中的一些会关闭)。 所以问题是:这种行为正常吗? DAO子类的使用示例:

  • 我们有一个spring-boot应用程序,它使用嵌入式tomcat进行部署,并使用MySQL后端的默认tomcat-jdbc连接池,而没有为MySQL或tomcat端定制。 该应用程序有一些调度程序,它们主要在一天中的特定时间运行,即在昨天的最后一次cron运行和今天的第一次cron运行之间,有超过9个小时的间隙。然而,无论何时cron在早期运行,它都从未遇到过空闲连接问题。 现在我们看到一条错误

  • 我们刚刚从dbcp迁移到tomcat jdbc连池。我们在加载中尝试了系统,收到了以下异常: 请注意: 不忙的连接在哪里?忙的数字在这之后一直在下降,但我们仍然没有得到任何连接。 有什么想法吗? 配置: env:ubuntu和tomcat 6. db-mysql

  • 我在项目中使用ApacheTomcat JDBC连接池。我很困惑,因为在重负下,我一直看到以下错误: 我的期望是,使用池,新连接的请求将被保留在队列中,直到连接可用。相反,当池达到容量时,请求似乎会被拒绝。这种行为可以改变吗? 谢谢, 达尔 这是我的池配置:

  • 这是我目前的配置 这是在全局上下文中,因此多个应用程序可以使用它。我对parameters.need一些细节有点困惑。我理解的是 池启动时创建的连接数。 一次最多可以激活50个连接。 10个连接在未使用连接时保持空闲,其他连接在 20个连接可以存储为空闲。 但当我启动tomcat服务器时,我可以看到30个空闲连接,这些连接将永远存在。为什么会这样?我错过什么了吗?根据我对连接池的理解,应该只创建1

  • Tomcat在使用后不释放连接的原因可能是什么? 这是我的配置