resin不断重启分析

线上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进行优化,对于优化效果不大的,从业务层上进行解决(多次查询,降低占用数据库连接的时间)。

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

猜你喜欢

转载自ni-de-yang-zi.iteye.com/blog/2249652