如何跟踪/记录tomcat dbcp池中的连接并检测不返回池连接的代码

如何跟踪/记录tomcat dbcp池中的连接并检测不返回池连接的代码,tomcat,logging,connection-pooling,apache-commons-dbcp,jdbc-pool,Tomcat,Logging,Connection Pooling,Apache Commons Dbcp,Jdbc Pool,在大型应用程序中的某个地方,有一些代码并没有像应该的那样返回到连接池的连接。结果是池很快达到最大连接数 这可以通过将其设置为删除放弃的连接来解决,但会降低性能 如何在tomcat dbcp中启用日志记录以显示何时借用和返回连接?记录连接借用和返回 我问这个问题是为了提供我自己的答案。可能不是很多人都有这个问题,但是跟踪那些保持连接打开的代码是一个真正的挑战。我已经在一个小型github项目中整合了这里描述的解决方案:。你可以去那里,也可以在这里继续简短的描述 在检查源代码之后,Tomcat DB

在大型应用程序中的某个地方,有一些代码并没有像应该的那样返回到连接池的连接。结果是池很快达到最大连接数

这可以通过将其设置为删除放弃的连接来解决,但会降低性能


如何在tomcat dbcp中启用日志记录以显示何时借用和返回连接?

记录连接借用和返回

我问这个问题是为了提供我自己的答案。可能不是很多人都有这个问题,但是跟踪那些保持连接打开的代码是一个真正的挑战。我已经在一个小型github项目中整合了这里描述的解决方案:。你可以去那里,也可以在这里继续简短的描述

在检查源代码之后,Tomcat DBCP似乎没有构建日志记录。我发现的最好的方法是使用AspectJ围绕从池中获取连接的方法和返回到池的连接的代码编织一个日志方法。在日志记录方法中,打印一个简短方便的调用跟踪,显示打开并返回连接的代码部分,如下所示:

+++ getConnection(52d02201): MyDAOSQL.getConnection(69) > MyDAOSQL.getCustomerByName(568) > ...
--- retConnection(52d02201): MyDAOSQL.getCustomerByName(568) > CustomerController.getCustomer(67) > ...
+++ getConnection(7100721a): MyDAOSQL.getConnection(69) > MyDAOSQL.getBasket(568) > ...
--- retConnection(7100721a): MyDAOSQL.getBasket(568) > CustomerController.getBasket(67) > ...
假设您在上下文xml中使用
java.sql.DataSource
,获取和返回连接的方法如下:

获取:
org.apache.tomcat.dbcp.dbcp2.poolgDataSource.getConnection

返回:
org.apache.tomcat.dbcp.dbcp2.poolgDataSource.PoolGuardConnectionWrapper.close

知道了这一点,就可以直接围绕这些方法编织日志方法,并使用AspectJ maven插件将其编译成代码,如下面的项目所示:我将这些文件放在一个小型github项目中:

日志记录工具的输出可以很容易地发现代码中连接没有关闭的地方

记录实际的sql活动


如果您想了解更多详细信息,可以使用p6spy(github中的搜索)之类的工具来跟踪JDBC层,直至sql查询。特别是使用maven安装它非常简单。

向我们展示如何配置tomcat池。您是使用数据源还是直接访问池?相关:只想感谢您的回答-它帮助我解决了一个困扰我几个月的问题