Apache意外停顿以发出请求

时间:2014-01-07 04:33:00

标签: java spring tomcat tomcat7 c3p0

运行Web应用程序一天后,登录正常加载但不起作用。日志在请求时显示tomcat暂停。

我正在使用:

  • 春季3
  • C3P0
  • MySQL的
  • 和Tomcat 7

日志如下:

Jan 06, 2014 9:56:18 PM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["http-bio-8080"]
Jan 06, 2014 9:56:18 PM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["ajp-bio-8009"]
Jan 06, 2014 9:56:18 PM org.apache.catalina.core.StandardService stopInternal
INFO: Stopping service Catalina
Jan 06, 2014 9:56:18 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 19 instance(s) to be deallocated for Servlet [Faces Servlet]
Jan 06, 2014 9:56:19 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 19 instance(s) to be deallocated for Servlet [Faces Servlet]
Jan 06, 2014 9:56:20 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 19 instance(s) to be deallocated for Servlet [Faces Servlet]
Jan 06, 2014 9:56:20 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 18 instance(s) to be deallocated for Servlet [default]
Jan 06, 2014 9:56:21 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 18 instance(s) to be deallocated for Servlet [default]
Jan 06, 2014 9:56:22 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 18 instance(s) to be deallocated for Servlet [default]
java.sql.SQLException: An SQLException was provoked by the following failure:        java.lang.InterruptedException
       at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)
       at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65)
       at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:62)
       at   com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:531)
       at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
       at com.tda.financiero.common.JasperReportProvider.llenarReporte(JasperReportProvider.java:116)
       at com.tda.financiero.common.JasperReportProvider.ejecutarReportePDF(JasperReportProvider.java:53)
       at com.tda.financiero.common.ReporteServiceImpl.generarFacturaPDF(ReporteServiceImpl.java:26)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:606)
       at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
       at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
           ...
Caused by: java.lang.InterruptedException
       at java.lang.Object.wait(Native Method)
       at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)
       at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
       at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
       at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
... 79 more
Jan 06, 2014 9:56:22 PM javax.faces.event.MethodExpressionActionListener processAction
SEVERE: Received 'java.lang.NullPointerException' when invoking action listener '#{userManagedBean.login()}' for component 'login'
Jan 06, 2014 9:56:23 PM javax.faces.event.MethodExpressionActionListener processAction
SEVERE: java.lang.NullPointerException
at org.apache.catalina.session.ManagerBase.generateSessionId(ManagerBase.java:807)
at org.apache.catalina.session.ManagerBase.createSession(ManagerBase.java:653)

日志还显示NullPointerException,但是在另一个异常之后。有任何想法吗?如果你能给我提示在哪里寻找或如何解决这个问题,那将是一件好事。谢谢!

修改

我使用Spring的applicationContext文件来配置c3p0池连接,所有DAO都使用sessionFactory,服务使用@Transactional注释。简而言之,Spring控制着连接。只有2个用户使用该应用程序,我认为使用c3p0默认值就足够了,所以我有了这个配置。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="testConnectionOnCheckin" value="true"/>
    <property name="idleConnectionTestPeriod" value="3600"/>  
    <property name="preferredTestQuery" value="SELECT 1" />             
</bean>

<!-- Session Factory Declaration -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.tda.financiero.domain.model"/>       
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <!-- <prop key="hibernate.show_sql">true</prop> -->  
        </props>
    </property>
</bean>

<!-- Enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>

<!-- Transaction Manager is defined -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
   <property name="sessionFactory" ref="sessionFactory"/>
</bean>

1 个答案:

答案 0 :(得分:1)

因此,您有一些客户端尝试从c3p0 DataSource检出Connections,但是wait()因为没有可用的Connections。在某些时候,那些线程是中断()编辑。不可能通过中断()编辑来形成上面列出的内容。它看起来并不像这些线程显式超时[c3p0有一个名为checkoutTimeout的配置参数],因为那时你会看到一个TimeoutException而不是InterruptedException

所以,有一点需要注意的是,这些线程中断了什么?它们是客户端线程,可能由Tomcat产生,而不是c3p0内部线程。 c3p0没有中断()它们。

另一个也许更有成效的事情是,为什么这些Threads等待()连接池中应该可用的Connections?您的连接池是否太小,无法承受它所遇到的负载,在这种情况下,最佳响应是增加c3p0参数maxPoolSize?连接池是否有如此多的负载,尽管有足够大的maxPoolSize,连接维护任务正在积压?在这种情况下,c3p0配置属性numHelperThreads可能有所帮助。

或者,也许是最常见的问题,您的应用程序是否会泄漏连接?也就是说,偶尔从DataSource检查出最终无法close()的连接?您的应用程序是否确保它检出的所有Connections都在finally块中关闭(),即使在清除finally块中的其他资源时发生异常?如果运行Java 7,您是否使用精彩的新try-with-resources语法获取Connections?

您没有提供有关应用程序的扩展,负载或配置的信息,但是连接泄漏是导致线程在尝试获取数据库连接时挂起太长时间的最常见原因。 c3p0有两个配置参数unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces来帮助您解决并(请!)调试并修复连接泄漏。请参阅讨论here

根据您提供的信息,使用这些参数检查您是否有参数泄漏是我尝试的第一件事。

但是,如果您知道应用程序的并发负载较高,则可以使用maxPoolSize。通过JMX,您可以监控c3p0的线程池是否跟上,或者您是否想要增加numHelperThreads