2014-12-05 80 views
3

我有一個java進程啓動大約60個線程,每個線程訪問MySql數據庫。連接池有益於多線程Java程序

我會使用像C3P0這樣的連接池嗎?還是僅僅意味着Web應用程序(可以擴展到很多用戶)?

今天我們有長期生活的JDBC連接(每個線程一個),而且我的計劃是在每次SQL查詢/插入之前,從連接池中獲取連接。

我想知道這是否會使我們的應用更穩定?另外,如果我將其配置爲匹配數據庫中的最大連接數,線程是否必須等待直到有空閒連接?文件不是很清楚(至少不適合我)。

任何指導表示讚賞!

+0

我不太瞭解這個應用程序的體系結構。你能拼出來嗎?我從你的描述中得到的結果是,這是一臺帶有數據庫後端的服務器,通過互聯網使用某個客戶端進行聯繫。如果是這樣的話,這和「Web應用程序」之間的唯一區別是它運行的是哪個端口,不是? – Mario 2014-12-05 16:03:30

+0

問題不在於架構,而在於關於連接池。 (粗魯的諷刺評論刪除)。問題是否Java會受益於使用連接池而不是長時間運行的JDBC連接(問題提到每個線程一個)。一個Web應用程序以一種完全不同的方式進行擴展(通常),您可以擁有1000個或更多的用戶。在這裏,我知道我只有一個進程,但有很多線程。我還能從使用連接池中獲益嗎? – 2014-12-05 17:11:11

+1

如果您在池中設置了最大連接數,池將不會再創建。如果給定時間點的所有連接都被其他線程佔用,則下一次檢索到的連接將被阻塞。 – omerkudat 2014-12-05 17:36:50

回答

1

如果不考慮應用程序在哪裏運行以及您的數據庫是否暴露於互聯網,我認爲添加連接池不會解決您的問題,但它可以改善您的應用程序。

我猜你在使用數據庫連接時發生虛假錯誤。我不認識你的特定錯誤,但這聽起來像某種連接失敗,如果你和數據庫之間的連接不可靠或速度慢,就會發生這種錯誤。游泳池在這裏無濟於事,因爲它是一個連接池。一旦你獲得連接,你不知道是否會因爲相同的原因而失敗。

但是,如果您確實使用了一個池,那麼您不必長時間保持連接打開狀態。有一個游泳池,你要求連接,如果沒有可用的連接,將創建一個連接。在您返回連接之後,它可能會(斷開連接)並在未使用一段時間後處置。除非您的應用程序使用每個連接都是恆定的,否則這對您的應用程序和服務器都會有好處。

即使在這裏,你也必須做一些額外的事情來處理失敗。假設您已經從游泳池獲得了連接,並且隨後失敗。您可以關閉它,並要求池建立新連接(池中應該有一些API來擺脫該連接)。新連接可能處於更好的狀態。

最後,考慮可能不使用互聯網上的JDBC。正如其他人可能會指出的那樣,這暴露了自己不必要的風險。也許使用某種類型的web服務來通過安全的https和更受限制的接口讀取和寫入數據。

+0

感謝您閱讀和回答我的問題,而不是蜿蜒進入建築問題!我們的應用程序嚴格用於室內使用,我們使用VPN和非標準端口,有防火牆等yada yada沒有什麼特別感興趣的問題。沒有什麼是暴露的,所以不要擔心。如果我一天有52個小時,我可能會爲這個特殊情況寫一個服務,但我有很多其他應用程序可供編寫,而這個應用程序並不重要。我更多地尋找「最佳實踐」。我想我現在明白如何使用它。再次感謝。 – 2014-12-05 18:38:37

2

您可能會從連接池中受益。 「通信鏈路故障」連同長壽命的JDBC連接使我懷疑連接在一段時間沒有被使用(空閒)後中斷。

HikariCP數據庫連接池爲你做兩件事情,可以幫助:

  • 檢查連接遞它之前是有效的。如果它無效,它將被丟棄,而另一個或有效的新連接將被分發。這一切都是由游泳池完成的,您的應用程序不需要照顧這一點。
  • 保持健康的連接通過關閉空閒連接(「的idleTimeout」)和循環長期連接(「maxLifetime」)。當壞的網絡組件(防火牆)丟棄任何打開時間超過30分鐘的連接時,後者特別有用。(*)

如果使用池中的所有連接,則線程可能必須等待(「connectionTimeout」)。但是,如果您的池具有適當的最大大小(「maximumPoolSize」),則很少會很長時間。它確實要求您的應用程序儘量減少使用連接的時間:在獲取連接和關閉連接(將連接返回到連接池)之間,應用程序應主要/僅執行數據庫操作。副作用是你需要的連接少得多:現在你使用60的地方,你可能會發現你只需要6個池。需要進行一些性能測試來確定適用於您的應用程序的正確「maximumPoolSize」。

我建議你嘗試使用和不使用連接池的「拔掉」測試。運行你的應用程序並給它做點什麼,拔掉網絡電纜,然後插回網絡電纜,看看你的應用程序恢復需要多長時間。在池中,只要池能夠創建與數據庫的新連接,應用程序就會再次正常運行。 (*)循環連接還有另一個原因:有些查詢可能會在數據庫服務器端產生臨時數據,並且只要連接處於活動狀態,數據庫服務器就可以保留這些數據。這可能會導致數據庫服務器的內存使用量不斷增加。我沒有看到過這種情況,但我知道其他人有。在這種情況下,「maxLifetime」選項非常有用。

+0

非常好,完整的答案! – 2015-01-04 12:11:11