2017-02-02 117 views
5

在池中各種原因連接可以變得無效:服務器連接超時,網絡問題......Tomcat的JDBC連接池:testOnBorrow VS testWhileIdle

我的理解是,一個Tomcat JDBC連接池不提供任何擔保它提供給應用程序的連接的有效性。

爲了防止(實際上只降低風險)從池中獲取無效連接,解決方案似乎是連接驗證的配置。驗證連接意味着在數據庫上運行一個非常基本的查詢(例如,MySQL上的SELECT 1;)。

Tomcat JDBC連接池提供了幾個選項來測試連接。我發現兩個更有趣的是testOnBorrowtestWhileIdle

首先,我認爲testOnBorrow是最好的選擇,因爲它基本上驗證連接,然後將其提供給應用程序(最大頻率由validationInterval定義)。

但是過了一秒,我意識到在使用它之前測試連接可能會影響應用程序的響應。所以我認爲使用testWhileIdle可以提高效率,因爲它在未使用時測試連接。

無論我選擇哪種方案,似乎他們只會降低獲取無效連接的風險,但這種風險依然存在。

所以我最終問:我應該使用testOnBorrowtestWhileIdle或兩者的組合?

在附註中,我很驚訝validationInterval不適用於testOnReturn,我沒有真正達到testOnConnect的目的。

回答

4

沒有100%正確的答案。這是一個權衡和背景的問題。

  • 大部分的時間,testOnBorrow是最危險的,因爲它確保了(因爲它可以最好),其從池中供您使用返回的連接之前,一個基本的完整性檢查已取得客戶端和db-server都在談論術語。
  • 它仍然不會阻止服務器連接的競爭狀態在'完整性檢查'時間&您的應用程序使用連接的時間之間。
  • 但考慮到這是一個角落案例,testOnBorrow提供了很好的保證。

  • 現在,換一種說法是,每次請求連接時,都會向數據庫服務器發出一個查詢(無論重量如何輕)。這可能非常快,但成本仍然不爲零。

如果你有一個繁忙的應用程序,具有很好的數據庫連接的可靠性,那麼你就開始從數據看,認爲「有效性檢查從池中的每個連接請求」的成本超過檢測連接問題的好處。

  • 在另一方面,如果你的應用是不是均勻忙(像大多數現實世界的應用程序),那麼它是非常有益的有testOnBorrow選項。
  • 它可以確保您在使用前擁有良好的連接。尤其是考慮到「失敗的數據庫操作」中的「無法輕鬆恢復」的成本(重試+手動干預+工作流程損失等)。

  • 現在想象一下如果您有testOnIdle選項。這要求在進行完整性檢查之前,您的連接閒置(取決於連接的空閒超時)。

  • 這是一個超過testOnBorrow的性能改進,但它有它自己的缺點。
    • 現實世界中的應用程序到數據庫的連接不只是空閒超時時間爲基礎的破損,他們可以根據防火牆規則,N/W擁堵,DB-服務器進行維護/修補等
    • 被丟棄
    • 因此,當您沒有任何「連接驗證」時,它可以回溯到數據中觀察到多少連接錯誤的數據測量。
  • 還有一件事這個選項需要注意是,當你有你的池的工作最好,最大的連接和您的應用程序運行良好,由於某種原因,如果你的數據庫服務器進行重新啓動或亦同。所有現場連接(從客戶角度來看)現在大部分會出錯,直到空閒超時啓動。所以你的數據庫問題(這可能是一場火拼)現在已經有點複雜了,直到應用程序連接再次恢復正常,或者重新啓動應用程序。

最後一個數據點是,對於某些應用程序來說,關鍵路徑不是「驗證查詢」時間(希望以較低的毫秒數)。應用程序有更大的問題需要處理。當然,對於某些應用,這段時間非常重要。

1

爲了讓您知道,我剛剛測試過這一點,可以同時使用testOnBorrowtestOnIdle屬性。

但是,如上所述,我將選擇testOnBorrow是唯一的,因爲我的應用程序沒有處於繁忙的通信量下,並且能夠承擔在驗證連接之前進行驗證。

正如評論中指出的那樣,testOnBorrow不需要驗證查詢。如果您選擇保留一個它可以是一個簡單的選擇:

jdbc.hive.testOnBorrow=true 
jdbc.hive.validationQuery=SELECT 1 

如果您想使用testWhileIdle,您可以使用以下命令:

jdbc.testWhileIdle=true 
jdbc.minEvictableIdleTimeMillis=1800000 
jdbc.timeBetweenEvictionRunsMillis=1800000` 

更多關於DCHP信息:https://commons.apache.org/proper/commons-dbcp/configuration.html

+0

實際上驗證查詢不是強制性的。如果未提供驗證查詢,則在連接上使用isValid方法。我認爲將連接驗證留給JDBC驅動程序是一個好主意。 –

+0

哦,看起來你是對的。只需閱讀文檔。將編輯帖子。 – UltimaWeapon