什么是调查Java中数据库连接使用情况的好工具?

Stu*_*ard 12 java database multithreading jdbc

什么是调查Java中数据库连接使用情况的好工具?

开发人员正在支持复杂的Java程序,该程序偶尔会耗尽可用的数据库连接数.由于问题是零星的,因此知道哪个线程已打开与数据库的多个连接以将工作集中在该区域中将是有用的.

最后,正确的修复似乎是重写程序以重用连接而不是每个线程打开多个连接.

我问,开发人员应该在他的工具箱中使用哪些工具来调查资源,即由线程分配的数据库连接.

ber*_*ami 7

看看log4jdbc.它使您可以查看jdbc上的所有内容,包括打开/关闭连接以及连接编号信息.


mat*_*tpr 4

不是特定的工具,而是一种调试技术,用于跟踪哪些代码负责打开连接或其他资源。

我假设您在java端使用一致的方法来获取数据库连接(池化与否并不重要)。

这个想法是围绕连接工厂/池或其他任何东西创建一个非常轻的包装类。包装器将实现任何有意义的 jdbc 接口,以便您可以将其替换为普通连接对象,但大多数方法只会透明地调用/返回底层连接。最简单的方法是扩展您的 DBConnection 类,并覆盖您需要监视的特定方法(不要忘记在super.method()适当的地方调用)。根据您的实现,您可能需要覆盖工厂和连接。

如果您使用某种 IoC 框架(例如 spring),您应该能够在配置级别轻松交换连接/工厂类。现在您的所有 Java 代码都将使用新的数据库连接包装器。

如果您使用的是池,那么调用connection.close()通常只是将对象返回到池中,而不是销毁连接。因此,该技术适用于正常连接泄漏和“未返回池(池耗尽)”泄漏。

现在我们只需要记录有趣的位并为泄漏的连接设置陷阱。

堆栈跟踪以识别创建者

在连接包装器的构造函数或工厂方法中,创建一个新Throwable对象并将其存储为包装器对象中的本地/成员变量以供稍后使用。我们使用 a 是Throwable因为它比使用 更快/更便宜Thread.currentThread().getStackTrace()。这Throwable记录/暗示请求/建立连接的呼叫者。

设下“陷阱”

finalize在包装类中实现该方法。这是当对象因不再使用而被销毁时 GC 调用的清理方法。

finalize方法应该检查“我关闭了吗?”。如果已经关闭,那么一切都很好...但是,如果连接正在被GC并且尚未关闭...那么这是一个“泄漏”连接。

现在又Throwable开始发挥作用了。我们可以抓取Throwable并输出一条不错的日志消息,内容如下:“我是一个泄漏的连接,这里是一个暗示我的创建者的堆栈跟踪。”

扩展这个想法

该方法可以适用于多种情况。当然,您可以在包装器中保留其他类型的数据,以解决您的特定问题。例如创建时间。然后,您可以轮询长期连接并再次暗示创建者。或者,您可以轮询现有连接并解析Throwable堆栈跟踪,以获取有关一段时间内哪些代码正在使用多少个连接的数据。

可能有一个现成的工具也可以完成这些类型的事情,但是在大多数情况下应用此技术所需的代码量非常少(假设您有一种简单的方法来交换您的数据库连接/工厂)无需搜索替换整个代码库)。但是,如果您需要搜索替换您的代码库情况...这是清理代码以使用依赖项注入或至少是一个中央工厂的绝佳机会,您可以在其中更轻松地测试和控制数据库访问。