簡體   English   中英

使用Guice Injections時如何正確處理Java中長期存在的MySQL連接?

[英]How to properly handle long-lived MySQL connections in Java when using Guice Injections?

我討厭陳述似乎在線上有很多解決方案的問題,但是我們似乎似乎無法為我們的案例找到任何有效的最佳實踐解決方案,因此感到別無選擇。

我們正在構建一個RESTful服務器應用程序,其中兩次使用之間的時間間隔可能從幾個小時到幾個月不等。

該服務器由Jetty托管。 我們沒有使用任何ORM,但是應用程序分為三層(WebService-,Business-和Data Layer)。 通過Guice框架注入的一類數據層存在。 JDBC(MySQL連接)在此類的構造函數中實例化。 剛開始,我們在連接過多時遇到了很多麻煩,然后我們才知道Guice默認情況下會在每個請求( ref )上創建新實例。 為了解決這個問題,並且由於我們的數據層類是有狀態的,我們將類注入為Singleton。

現在我們已經預見到,如果一段時間不使用REST應用程序,可能會遇到麻煩,因為連接將超時,並且不會實例化新的連接,因為構造函數將僅被調用一次。

我們現在有多種解決方案,但是我們似乎無法找出解決此問題的最佳方法,因為它們似乎都沒有那么好。 對於其他解決方案的任何輸入或建議,將不勝感激。

1.延長配置的mysql超時間隔我們確實不希望這樣做,因為我們認為這並不是最佳實踐。 我們當然不應該有任何泄漏的連接對象,但是如果有的話,它們將填滿可用連接的可用空間。

2.在每種方法的開頭實例化一個新連接,然后在結束時將其關閉。據我們所知,這根本不是最佳實踐,因為這會導致大量的開銷,如果可能,應避免使用?

3.將注入更改回“每個請求”,並在每種方法結束時關閉池。這比#2還要糟糕,因為我們不僅要實例化一個新的連接,還要實例化每個對象上的一個新對象。請求?

4.在每種方法的開頭檢查連接的狀態,並在關閉的情況下實例化一個新連接。一個例子是對mysql進行ping( 示例 )操作,如果它拋出異常,則實例化一個新連接。 這會起作用,但是會產生一些開銷。 是否知道此輸入是否會對性能產生任何影響?

5.明確捕獲方法中拋出的任何異常,這些異常表明該連接已斷開,如果是這樣,則實例化一個新的連接 。這樣,我們將擺脫ping開銷,但它將使我們的代碼顯着復雜化找出一種方法來確保如果連接已經存在,這些方法將返回其應返回的結果。

6.使用連接池除了使用應用程序服務器(例如Glassfish)外,我們都不熟悉連接池。 我們還想知道這是否真的可以解決我們的問題? 如果是這樣; 關於為我們提供連接池的任何框架有什么建議嗎? 在這里,他們建議將PLUS與Jetty一起使用。

請詢問是否有任何不清楚的地方。 我可能忘了添加一些重要信息。 對我來說,這更多是一個設計問題,但是如果有人認為有幫助,我將很高興提供任何代碼。

提前致謝!

連接池是解決之道。
它們具有許多優點:

  1. 他們為您檢查您的連接-處理超時
  2. 它們控制連接數
  3. 完成后,您只需關閉連接即可-無需保留引用

您當然應該將連接保留在某種類型的池中,實際上,如果您不硬着頭皮,幾乎可以肯定最終最終會自己寫一個。 在您實施連接檢查以免它們過時時,有了某種連接器,這樣您就無需每次都重新打開它們了,某種異常處理代碼...讓我不知所措。
我使用過dbcpboneCP ,它們都非常易於使用和配置,將為您節省數小時的處理JDBC連接問題的麻煩
我對Guice不太熟悉,但是我認為它有某種方法可以為Object提供自己的工廠方法,因此您可以使用它來從池中獲取連接,然后在完成將它們返回到之后簡單地調用close() 。游泳池。
如果您使用的是Web服務器,則始終可以使用interceptorfilter將連接綁定到工作線程,並在處理后丟棄它們,在這種情況下,您的連接提供程序將只需要拉扯與當前線程綁定的連接。

相反,注入Provider<Connection>並讓提供者從可以檢測到陳舊條目的連接池中釋放連接(編輯:在需要時)。

未返回的連接應從池中丟棄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM