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

Posted

技术标签:

【中文标题】如何跟踪/记录 tomcat dbcp 池中的连接并检测不返回连接池的代码【英文标题】:How to track/log connections in tomcat dbcp pool and detect code that does not return connection to the pool 【发布时间】:2016-03-16 05:55:51 【问题描述】:

在大型应用程序的某个地方,有一段代码没有按应有的方式返回连接池的连接。结果是池很快达到了最大连接数。

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

如何启用登录 tomcat dbcp 以显示何时借用和返回连接?

【问题讨论】:

向我们展示您是如何配置 tomcat 池的。你是使用数据源还是直接访问池? 相关:How to log Tomcat 7 JDBC connection pool, connection creation 【参考方案1】:

记录连接借用和归还

我问这个问题是为了提供我自己的答案。可能没有很多人有这个问题,但跟踪打开连接的代码是一个真正的挑战。我已经将这里描述的解决方案放在了一个小型 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 安装它非常简单。

【讨论】:

只想对这个答案表示感谢 - 它帮助我解决了困扰我数月的问题

以上是关于如何跟踪/记录 tomcat dbcp 池中的连接并检测不返回连接池的代码的主要内容,如果未能解决你的问题,请参考以下文章

登录 DBCP

tomcat jdbc 连接池中缺少连接

部署在 Tomcat 上的 DBCP 中的死锁问题

连接池中没有合适的驱动程序异常

连接池泄漏原因

tomcat dbcp 和 mysql 连接池