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

时间:2015-12-10 14:36:01

标签: tomcat logging connection-pooling apache-commons-dbcp jdbc-pool

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

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

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

1 个答案:

答案 0 :(得分:4)

记录连接借用并返回

我问这个问题是为了提供我自己的答案。可能不是很多人都有这个问题,但是跟踪连接打开的代码是一个真正的挑战。我已将这里描述的解决方案放在一个小的github项目中:https://github.com/chronakis/dbcp-conn-log。你可以去那里或继续在这里做一个简短的描述。

在检查源之后,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.PoolingDataSource.getConnection
返回:org.apache.tomcat.dbcp.dbcp2.PoolingDataSource.PoolGuardConnectionWrapper.close

了解这一点,可以直接围绕这些方法编写日志记录方法,并使用AspectJ maven插件将其编译到代码中,如下所示:我将这些文件放在一个小的github项目中:https://github.com/chronakis/dbcp-conn-log

日志记录工具的输出使您可以轻松找到代码连接中的关闭位置。

记录实际的sql活动

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