简体   繁体   English

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

[英]How to track/log connections in tomcat dbcp pool and detect code that does not return connection to the pool

Somewhere in a large application, there is some piece of code that does not return a connection to the connection pool as it should.在大型应用程序的某个地方,有一些代码没有像它应该的那样返回到连接池的连接。 The result is that that the pool reaches quickly the maximum connections.结果是池快速达到最大连接数。

This can be worked around by setting it to remove abandoned connections, but it reduces performance.这可以通过将其设置为删除废弃连接来解决,但会降低性能。

How can I enable logging in tomcat dbcp to show when connections are borrowed and returned?如何启用登录 tomcat dbcp 以显示何时借用和返回连接?

Logging connection borrowing and returning记录连接借用和归还

I asked this question to provide my own answer.我问这个问题是为了提供我自己的答案。 Probably not a lot of people have this problem, but it was a real challenge tracking down the code that left the connections open.可能没有多少人有这个问题,但追踪导致连接打开的代码是一个真正的挑战。 I have put together the solution described here in a small github project: https://github.com/chronakis/dbcp-conn-log .我已经在一个小型 github 项目中汇总了此处描述的解决方案: https : //github.com/chronakis/dbcp-conn-log You can go there or continue for a short description here.您可以去那里或在此处继续进行简短说明。

Tomcat DBCP does not seem to have built logging, after inspecting the source.检查源代码后,Tomcat DBCP 似乎没有构建日志记录。 The best way I found was to use AspectJ to weave a logging method around the methods that get the connection from the pool and the code that returns the connection to the pool.我发现的最好方法是使用 AspectJ 围绕从池中获取连接的方法和将连接返回到池的代码编写日志记录方法。 The logging methods, print a short convenient call trace that shows the part of the code that opens and returns the connections as follows:日志记录方法,打印一个简短的调用跟踪,显示打开和返回连接的代码部分,如下所示:

+++ 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) > ...

Assuming you are using the java.sql.DataSource in the context xml, the methods that are getting and returning the connections are:假设您在上下文 xml 中使用java.sql.DataSource ,获取和返回连接的方法是:

Get: org.apache.tomcat.dbcp.dbcp2.PoolingDataSource.getConnection获取: org.apache.tomcat.dbcp.dbcp2.PoolingDataSource.getConnection
Return: org.apache.tomcat.dbcp.dbcp2.PoolingDataSource.PoolGuardConnectionWrapper.close返回: org.apache.tomcat.dbcp.dbcp2.PoolingDataSource.PoolGuardConnectionWrapper.close

Knowing this, it is straightforward to weave logging methods around these methods and compile it into the code using AspectJ maven plugin as shown the project here: I have put together the those files in a small github project: https://github.com/chronakis/dbcp-conn-log知道了这一点,围绕这些方法编织日志记录方法并使用 AspectJ maven 插件将其编译到代码中是很简单的,如此处所示的项目:我已将这些文件放在一个小型 github 项目中: https : //github.com/ chronakis/dbcp-conn-log

The output from the logging tool makes it easy to spot where in the code connections don't close.日志工具的输出可以很容易地发现代码连接没有关闭的地方。

Logging the actual sql activity记录实际的 sql 活动

If you want further detail, you can use something like p6spy (search in github) to track the JDBC layer down to the sql queries.如果您需要更多详细信息,可以使用 p6spy(在 github 中搜索)之类的东西来跟踪 JDBC 层到 sql 查询。 Installing it especially with maven is pretty simple.尤其是使用 maven 安装它非常简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM