調查Java中的數據庫連接使用情況的好工具是什麼?調查Java中數據庫連接用法的好工具是什麼?
開發人員正在支持一個複雜的Java程序,該程序用盡了許多可用的數據庫連接。由於問題是零星的,因此知道哪個線程已經打開了與數據庫的多個連接以將精力集中在該區域將是有用的。
最後,正確的修復似乎是重寫程序以重新使用連接,而不是每個線程打開多個連接。
我在問,開發人員在他的工具箱中應該使用哪些工具來調查資源,即由線程分配的數據庫連接。
調查Java中的數據庫連接使用情況的好工具是什麼?調查Java中數據庫連接用法的好工具是什麼?
開發人員正在支持一個複雜的Java程序,該程序用盡了許多可用的數據庫連接。由於問題是零星的,因此知道哪個線程已經打開了與數據庫的多個連接以將精力集中在該區域將是有用的。
最後,正確的修復似乎是重寫程序以重新使用連接,而不是每個線程打開多個連接。
我在問,開發人員在他的工具箱中應該使用哪些工具來調查資源,即由線程分配的數據庫連接。
不是一個特定的工具,而是用於追蹤哪些代碼負責打開連接或其他資源的調試技術。
我假設你正在java端使用一致的方法來獲得數據庫連接(合併或不是無關緊要)。
這個想法是創建一個非常輕的包裝類圍繞您的連接工廠/池或任何它。包裝器將實現任何jdbc接口的意義,所以你可以將它換成你的普通連接對象,但大多數方法只是透明地調用/返回底層連接。
如果您使用的是某種IoC框架(例如spring),您應該可以在配置級別輕鬆更換連接/工廠類。現在你所有的java代碼都將使用你的新的db連接包裝器。
如果您使用的是池,那麼調用connection.close()
通常只是將對象返回到池而不是銷燬連接。所以這種技術適用於正常的連接泄漏,或者只是「不返回到池(池已耗盡)」泄漏。
現在我們只需要記錄有趣的位並設置泄漏連接的陷阱。
在構造函數或工廠方法爲您的連接包裝創建一個新的Throwable
對象,並將其存儲爲您的包裝供以後中的一個局部變量。我們使用Throwable
,因爲它比使用Thread.currentThread().getStackTrace()
更快/更便宜。
實現你的包裝類的finally
方法。這是GC在對象因爲不再使用而被銷燬時所調用的清理方法。
finally
方法應檢查「我關閉了嗎?」。如果已經關閉,那麼一切都很好......但是如果連接正在GC中並且它尚未關閉......那麼這是一個「泄露」連接。
現在Throwable
重新發揮作用。我們可以抓住Throwable
並輸出一條不錯的日誌消息,如下所示:「我是一個泄漏連接,這是一個跟蹤我的創建者的堆棧跟蹤。」
該方法可適用於各種情況。您當然可以在包裝中保存其他類型的數據,以解決您的特定問題。例如創建時間。然後,您可以輪詢長期連接並再次牽連創建者。或者您可以輪詢現有連接並解析堆棧跟蹤,以獲取哪些代碼正在使用一段時間內有多少個連接的數據。
有可能是現成的工具,也可以做這些類型的東西,但應用這種技術所需的代碼量在大多數情況下是非常小的(假設你有一個簡單的方法來交換我們的你的db連接工廠沒有搜索 - 替換你的整個代碼庫)。
看一看log4jdbc。它使您能夠查看所有通過您的jdbc的內容,包括打開/關閉連接以及連接號碼信息。
連接池可以給你一些診斷。例如檢查debugUnreturnedConnectionStackTraces屬性C3P0連接池:
http://www.mchange.com/projects/c3p0/index.html#debugUnreturnedConnectionStackTraces
有人向我展示了ConnLeakFinder近日,「一個簡單的工具,以查明JDBC連接泄漏在Java代碼中」。我到目前爲止還沒有對其進行測試,但它應該允許您使用以查看誰沒有關閉連接。見Connection+Leak+How+To+Find.htm。
但的確,您應該使用連接池的承銷商(例如c3p0)。
P6Spy是一個開源框架,支持攔截和可選修改數據庫語句的應用程序。
從http://www.p6spy.com/about.html
的P6SPY分佈包括以下模塊:
雖然P6Spy是一個很好的工具,但我不明白它是如何幫助狩獵連接泄漏問題。 – 2010-01-21 09:18:10