Tomcat在Spring Boot应用程序中挂起

时间:2016-04-05 22:02:32

标签: spring tomcat spring-boot threadpool connection-pooling

我正在使用 Spring启动,SQL server activiti,websocket和angularJS 的Web应用程序中工作。

有时,此应用程序UI会挂起(并非总是如此)。我怀疑这是因为连接池。此应用程序使用Spring Boot中的默认数据源属性。到目前为止,没有连接池库

问题:

我怀疑线程正在等待数据库连接,所以......

1)增加最大活动连接可以解决这个问题吗?

2)使用连接池库可以解决这个问题吗?

我在下面添加了线程转储....

    MessageBrokerSockJS-3 prio=10 tid=0x00007f8c1c3d1800 nid=0xebd in  Object.wait() [0x00007f8c609c2000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007095cd788> (a org.apache.commons.pool.impl.GenericObjectPool$Latch)
    at java.lang.Object.wait(Object.java:503)
    at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1118)
    - locked <0x00000007095cd788> (a org.apache.commons.pool.impl.GenericObjectPool$Latch)
    at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:204)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
    at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
    at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
    at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
    at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
    at org.activiti.engine.impl.AbstractQuery.list(AbstractQuery.java:138)
    at com.rbccm.workflow.db.dao.ActivitiHelper.getTasksByTaskLocalVar(ActivitiHelper.java:305)
    at com.rbccm.workflow.db.dao.ActivitiHelper$$FastClassBySpringCGLIB$$86c44488.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:649)
    at com.rbccm.workflow.db.dao.ActivitiHelper$$EnhancerBySpringCGLIB$$71f2d0fd.getTasksByTaskLocalVar(<generated>)
    at com.rbccm.workflow.manager.ActivitiManager.getTasksByTaskLocalVar(ActivitiManager.java:861)
    at com.rbccm.workflow.manager.ActivitiManager$$FastClassBySpringCGLIB$$f69deb1c.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:649)
    at com.rbccm.workflow.manager.ActivitiManager$$EnhancerBySpringCGLIB$$31946c7.getTasksByTaskLocalVar(<generated>)
    at com.rbccm.workflow.manager.AlfrescoManager.unlockTaskForClosedDocument(AlfrescoManager.java:37)
    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.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

"MessageBrokerSockJS-2" prio=10 tid=0x00007f8c1e484000 nid=0xebc waiting on condition [0x00007f8c60ac4000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007041a9590> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1085)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

"MessageBrokerSockJS-1" prio=10 tid=0x00007f8c1c9c6000 nid=0xeb6 in Object.wait() [0x00007f8c60bc4000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007095d02d8> (a org.apache.commons.pool.impl.GenericObjectPool$Latch)
    at java.lang.Object.wait(Object.java:503)
    at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1118)
    - locked <0x00000007095d02d8> (a org.apache.commons.pool.impl.GenericObjectPool$Latch)
    at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:391)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:549)
    at com.rbccm.workflow.db.dao.ChaserDao.clearOldChasers(ChaserDao.java:111)
    at com.rbccm.workflow.db.dao.ChaserDao$$FastClassBySpringCGLIB$$fa074cd3.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at com.rbccm.workflow.db.dao.ChaserDao$$EnhancerBySpringCGLIB$$48b6e5eb.clearOldChasers(<generated>)
    at com.rbccm.workflow.sendchaser.SendChaser.checkChasers(SendChaser.java:72)
    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.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

"container-0" prio=10 tid=0x00007f8c1c930000 nid=0xeb5 waiting on condition [0x00007f8c60cc6000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at org.apache.catalina.core.StandardServer.await(StandardServer.java:407)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer$1.run(TomcatEmbeddedServletContainer.java:146)

"ContainerBackgroundProcessor[StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]" daemon prio=10 tid=0x00007f8c149fa000 nid=0xeb4 waiting on condition [0x00007f8c60dc7000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1345)
    at java.lang.Thread.run(Thread.java:745)

1 个答案:

答案 0 :(得分:0)

感谢@Kedar Parikh,您提供的链接对于读取线程转储并找到此问题的根本原因非常有用。

从这个问题的堆栈跟踪,下面的行表示,该线程正在等待从池中借用(获取)数据库连接。

org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1118)

在这种情况下,Tomcat挂起,因为某些线程正在等待数据库连接

当我回答我自己的(另一个)问题时,我能够监控我的数据库连接池。 通过使用此监视器/日志记录,我在应用程序中发现了连接泄漏。

有关如何监视/记录数据库连接池的更多详细信息,请参阅 How to Debug / Log Tomcat JDBC Connection Pool's connections?