【问题标题】:Apache pauses unexpectedly to make a requestApache 意外暂停以发出请求
【发布时间】:2014-01-07 04:33:00
【问题描述】:

在运行 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>

【问题讨论】:

    标签: java spring tomcat tomcat7 c3p0


    【解决方案1】:

    因此,您有一些客户端尝试从 c3p0 数据源签出连接,但由于没有可用的连接而等待()。在某些时候,这些线程被中断()。不可能通过它们被中断()来说明您上面列出的内容。看起来这些线程并没有显式超时 [c3p0 有一个名为 checkoutTimeout 的配置参数],因为那样你会看到 TimeoutException 而不是 InterruptedException

    所以,有一点值得怀疑的是,是什么打断了这些线程?它们是客户端线程,可能由 Tomcat 产生,而不是 c3p0 内部线程。 c3p0 没有中断()他们。

    另一个可能更高效的问题是,为什么这些线程等待()连接本应在连接池中可供它们使用的连接?您的连接池对于它所经历的负载是否太小,在这种情况下,最好的响应是增加 c3p0 参数maxPoolSize?连接池的负载是否如此之大,以至于尽管maxPoolSize 足够大,但连接维护任务却积压了?在这种情况下,c3p0 配置属性 numHelperThreads 可能会有所帮助。

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

    您没有提供有关应用程序的规模、负载或配置的信息,但到目前为止,连接泄漏是线程在尝试获取数据库连接时挂起时间过长的最常见原因。 c3p0 有两个配置参数unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces 来帮助您解决和(请!)调试和修复连接泄漏。见讨论here

    鉴于您提供的信息,我首先会尝试使用这些参数检查您是否有参数泄漏。

    不过,如果您知道您的应用具有高并发负载,您可能会使用maxPoolSize。并且通过 JMX,您可以监控 c3p0 的线程池是否跟上,或者您是否想增加numHelperThreads

    【讨论】:

    • 感谢您回答史蒂夫,我用新信息更新了我的问题。
    • 嗨。如果您的应用程序最多有 2 个客户端,则连接泄漏很可能是问题所在。请尝试配置 unreturnedConnectionTimeout 和 debugUnreturnedConnectionStackTraces,然后查找 INFO 中记录的堆栈跟踪。
    猜你喜欢
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 2020-12-31
    • 1970-01-01
    相关资源
    最近更新 更多