关于java.sql.SQLRecoverableException: Closed Connection异常的解决方案

来源:互联网 发布:网络诈骗的手段 编辑:程序博客网 时间:2024/06/05 20:20

在项目中碰到了一个应用异常,从表象来看应用僵死。查看Weblogic状态为Running,内存无溢出,但是出现多次线程堵塞。查看Weblogic日志,发现程序出现多次Time Out。

 <Error> <WebLogicServer> <BEA-000337> <[STUCK] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "640" seconds working on the request "Workmanager: default, Version: 0, Scheduled=true, Started=true, Started time: 640083 ms", which is more than the configured time (StuckThreadMaxTime) of "600" seconds. Stack trace:java.net.SocketInputStream.socketRead0(Native Method)java.net.SocketInputStream.read(SocketInputStream.java:129)oracle.net.ns.Packet.receive(Packet.java:300)oracle.net.ns.DataPacket.receive(DataPacket.java:106)oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315)oracle.net.ns.NetInputStream.read(NetInputStream.java:260)oracle.net.ns.NetInputStream.read(NetInputStream.java:185)oracle.net.ns.NetInputStream.read(NetInputStream.java:102)oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137)oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290)oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:884)oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1167)oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1289)oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3593)oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3637)oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1495)com.trs.infra.persistent.BaseObjs.loadPage(BaseObjs.java:615)com.trs.infra.persistent.BaseObjs.ensurePageLoaded(BaseObjs.java:552)com.trs.infra.persistent.BaseObjs.getAt(BaseObjs.java:1500)com.trs.infra.support.log.LogServer.initOperTypeMap(LogServer.java:570)com.trs.infra.support.log.LogServer.getOperTypeAsInt(LogServer.java:105)com.trs.infra.support.log.LogServer.save(LogServer.java:81)com.trs.infra.support.log.LogServer.startRecord(LogServer.java:630)com.trs.infra.support.log.LogServer.startRecord(LogServer.java:646)com.trs.presentation.util.LoginHelper.login(LoginHelper.java:342)jsp_servlet._app.__login_dowith._jspService(__login_dowith.java:446)weblogic.servlet.jsp.JspBase.service(JspBase.java:34)weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)weblogic.servlet.internal.ServletStubImpl.onAddToMapException(ServletStubImpl.java:453)weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:364)weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)com.trs.deployer.domain.filter.DeployerControllerFilter.doFilter(DeployerControllerFilter.java:88)weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)com.trs.servlet.AclFilter.doFilter(AclFilter.java:54)weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)com.trs.servlet.LoginCheckFilter.doFilter(LoginCheckFilter.java:126)weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)com.trs.cluster.ext.wcm.ClusterProxyFilter.doFilter(ClusterProxyFilter.java:65)weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)com.trs.infra.session.util.SessionFilterBase.doFilter(SessionFilterBase.java:128)weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3296)weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3262)weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2171)weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2097)weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2075)weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1514)weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
我们知道,Weblogic会自动检测线程运行超时,当超过特点时间(默认600S),即认为此线程为堵塞线程。在日志中发现多次堵塞线程,通过查找资料,发现Weblogic在发生多次线程堵塞后,会自动把应用挂起。默认次数为15次。

是什么造成了线程堵塞呢?通过进一步分析日志,我们发现在线程堵塞之前,发生了多次java.sql.SQLRecoverableException: Closed Connection异常。异常情况:

java.sql.SQLRecoverableException: Closed Connectionat oracle.jdbc.driver.PhysicalConnection.needLine(PhysicalConnection.java:5389)at oracle.jdbc.driver.OracleStatement.closeOrCache(OracleStatement.java:1578)at oracle.jdbc.driver.OracleStatement.close(OracleStatement.java:1563)at oracle.jdbc.driver.OracleStatementWrapper.close(OracleStatementWrapper.java:94)at oracle.jdbc.driver.OraclePreparedStatementWrapper.close(OraclePreparedStatementWrapper.java:82)at com.trs.infra.persistent.BaseObj.update(BaseObj.java:1733)at com.trs.cms.content.CMSObj.update(CMSObj.java:402)at com.trs.cms.auth.persistent.User.update(User.java:798)at com.trs.cms.auth.persistent.User.login(User.java:890)at com.trs.presentation.util.LoginHelper.login(LoginHelper.java:371)at jsp_servlet._app.__login_dowith._jspService(__login_dowith.java:446)at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)at com.trs.deployer.domain.filter.DeployerControllerFilter.doFilter(DeployerControllerFilter.java:88)at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)at com.trs.servlet.AclFilter.doFilter(AclFilter.java:54)at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)at com.trs.servlet.LoginCheckFilter.doFilter(LoginCheckFilter.java:126)at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)at com.trs.cluster.ext.wcm.ClusterProxyFilter.doFilter(ClusterProxyFilter.java:65)at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)at com.trs.infra.session.util.SessionFilterBase.doFilter(SessionFilterBase.java:128)at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3296)at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3262)at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2171)at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2097)at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2075)at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1514)at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
从表现来看是数据库连接出了异常。我们对数据库和网络进行了分析,确定数据库和网络都无异常。我们的另外一个应用在Weblogic运行没有类似问题。

最后在Oracle的论坛上找到了问题的根结,由于我们的应用是自己开发的数据库连接池,应用和数据库之间有一层防火墙。防火墙策略是对于1800s未使用的Socket连接将自动关闭。Oracle的日志中也发现Socket异常关闭的异常。我们对应用进行了调整,当连接池中的连接15分钟不用时,自动回收,问题解决。