连接池维护心得

连接池连接维护心得
最近系统连接池连接出现了连接数持续上涨的问题,我们对连接池的所有的参数研究发现时代码中没有关闭连接,后来找到代码中的连接,将其关闭。先将查找心得整理如下:
我们知道连接池有removeAbandoned removeAbandonedTimeout logAbandoned这三个属性,removeAbandoned removeAbandonedTimeout 两个属性配合使用可以将指定时间内没有关闭的connection回收关闭。
设置了这几个属性后,连接池连接数的状态是这样的,如果存在没有关闭的连接,连接池会每隔removeAbandonedTimeout设置的时间,检测一下连接池的连接数和连接状态,如果当连接池中活动的连接数大于maxActive设置的最大连接数时,将会启动连接回收,这个连接回收是不会将连接回收到连接池重复利用,而是直接销毁这些连接。在这个时候连接池的连接数会突然下降至当前需要的连接,而这些连接是连接池重新产生的,不是回收利用的。
如果持续发现这种情况,而且这些连接在数据库总的状态一直是sleep状态,我个人觉得,就应该是程序中没有正常关闭连接了。我们就需要在程序中找到这个连接。恰恰连接池提供了logAbandoned属性,如果将其设置为true,那么在出现上述情况时,关闭的连接信息打印到日志,类似的打印日志如下:
DBCP object created 2011-04-14 11:22:18 by the following code was never closed:
java.lang.Exception
        at org.apache.tomcat.dbcp.dbcp.AbandonedTrace.setStackTrace(AbandonedTrace.java:160)
        at org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:86)
        at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:96)
        at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
        at org.yeeda.costexpress.util.ConnectionPool.getConnection(Unknown Source)
        at org.yeeda.costexpress.service.member.impl.MyMaterialServiceImpl.exportExcel(Unknown Source)
        at org.yeeda.costexpress.servlet.member.MyMaterialServlet.toExcel(Unknown Source)
        at org.yeeda.costexpress.servlet.member.MyMaterialServlet.doPost(Unknown Source)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.yeeda.costexpress.filter.AutoLoginFilter.doFilter(Unknown Source)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:619)


这个相当于异常处理,程序不会报错。但是我们可以通过异常信息找到到底是哪里的connection没有关闭,能够找到代码的位置,然后仔细分析代码,看从连接池的拿到的连接到底执行了close()方法没有。如果出现上述那样的情况,一般是没有关闭的。
这次通过我对源代码的分析,发现执行关闭的connection是个空值,是程序初始化是赋的值,但是真正执行任务的connection是程序员从连接池中拿的,但是并没有赋给类connection属性,但是它最后调用关闭的方法是框架里写好的,(可能是从别的地方复制过来的)但是框架写好的方法是关闭调用类得connection属性。所以这样导致了,一个空值传给关闭connection的方法,而真正从连接池拿来的connection却还在逍遥法外。
通过这样的错误,我意识到,有时候我们程序员编程,淹没在无穷的代码中,可能会很累,很烦,感觉系统框架的一些方法太麻烦,在一些应用中懒得去用,使用直接的方法还快,省事一些,但是在方法的其他地方又用了框架的东西,很多情况下,像今天这样,表面上万无一失,却真正出了问题。
我感觉我们在编程的时候,可以临时发挥,走比较有效的路线,但是如果我们的思路脱离了框架,在方法写完时,再整体检查一下,确保万无一失。

你可能感兴趣的:(java,apache,tomcat,编程,框架)