欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

resin不断重启分析 博客分类: java Pool closed dbcpunable to create new native threadoutOfMemoryError 

程序员文章站 2024-03-01 22:56:46
...

线上resin服务跑一段时间就会抛出以下这个异常,导致服务不断重启,用的是spring+ibatis+mysql

这个问题如何解决?

数据库连接池配置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close">

<property name="driverClassName" value="com.mysql.jdbc.Driver" />

<property name="url" value="${env.mysql.jdbc.url}" />

<property name="username" value="${env.mysql.username}" />

<property name="password" value="${env.mysql.password}" />

<property name="defaultAutoCommit" value="true"></property>

</bean>

 

Caused by: java.lang.IllegalStateException: Pool closed

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

        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:115)

        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:430)

        at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:202)

        ... 50 more

 

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.lang.IllegalStateException: Pool closed

 

异常追加:java.lang.outOfMemoryError:unable to create new native thread 

导致resin不断的重启

 

 

问题分析:

线上服务resin不断自动重启,出现了2次,异常如上,

第一次出现后分析可能有两种原因:

1.可能是程序里面线程池的数目设置过大

2.数据库最大链接数目设置不合理

所以根据以上2点做了相关优化,调小程序里面连接池的数目,将数据库最大链接数调大

优化完毕后,貌似起到了一定的效果。可是一个多月后这个问题再次重现,并且这次持续时间相当长,大约有半个小时。

痛定思痛,又根据异常分析,表面上看是线程数创建过多,导致内存溢出,没有足够的内存创建新的线程,网站上的表象就是访问超慢或者压根访问不了。

由于程序已经正常运行了半个月,先排除代码的问题。猜测是不是数据库方面的原因,随即联系dba找出当时异常时间点数据库方面的相关日志,发现在resin不断重启前,有几个sql执行的效率相当低下,达到了好几百秒,这完全已经不正常。由于执行相当慢,表被锁了,但大量的查询还在不断的涌入,大量sql直接被阻塞,数据库链接耗尽,无法创建新的链接。线程数目不断的增加,旧有线程占用内存又没释放,直到web容器的承受不了后,就开启了自动重启的保护机制。

 

解决方案:找出了那几个查询相当慢的sql。逐个进行分析,对sql进行优化,对于优化效果不大的,从业务层上进行解决(多次查询,降低占用数据库连接的时间)。

 

优化完毕后,重新部署运行,持续观察中。。。。。