在大型应用程序的某个地方,有一些代码不会像应该的那样返回到连接池的连接.结果是池快速达到最大连接.
这可以通过将其设置为删除已放弃的连接来解决,但会降低性能.
如何在tomcat dbcp中启用日志记录以显示何时借用和返回连接?
记录连接借用和返回
我问这个问题以提供自己的答案。可能没有多少人遇到这个问题,但这是一个真正的挑战,要在连接断开的情况下跟踪代码。我在一个小型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) > ...
假设您java.sql.DataSource
在上下文xml中使用,则获取和返回连接的方法是:
获取: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进行安装非常简单。