有客戶說,他們通過connection pool監控發現weblogic92連接池中當前連接數(current
capacity)小於初始連接數(initial
capacity)。從現象上來說,給客戶的直覺是:連接池初始化有問題,沒有幫助他們初始化他們需要的那么多連接。但他同時發現,幾個connection
pool中,其他pool沒有問題。拿到問題,我也懷疑這可能是weblogic的一個bug,但隨后從客戶發送過來的日志中發現出問題的connection被disable過。調查后發現問題的確和這個pool被disable過有關,那么為什么pool被disable后,會出現這樣的問題呢?
首先我們看看這個pool為什么會被disable?
手工強制suspend連接池、數據庫關閉、網絡不穩定等因素都可能成為connection
pool被disable的誘因。從客戶的日志中,我能看到大量的如下異常,
1:java.net.SocketException: 管道已斷開
(errno:32)
2:weblogic.common.resourcepool.ResourceDisabledException: Pool
JDBC Data Source-0 is disabled, cannot allocate resources to
applications.
根據上面的異常,首先跟客戶確認是否存在過數據庫關閉、強制disable
connection的操作,這些都被客戶否定了,那么最大可能的原因就是網絡不穩定,網絡是好時壞的話,很容易造成weblogic連接池中到database
server的連接中斷,從而導致connection pool被disable。
那么為什么連接中斷會引起connection
pool被disable呢?這里要談到兩個參數:CountOfTestFailuresTillFlush、CountOfRefreshFailuresTillDisable。這兩個參數在weblogic連接池實現中由於控制是否、何時flush或disable連接池,兩個都是指連續幾次失敗操作(test、refresh)后去flush或disable
connection
pool。注意:這是說的是連續,而不是間斷,每次成功操作(test、refresh)后,這兩個值都會被reset成0。默認情況下這兩個值均為2,即連續失敗3(2+1)次后,connection
pool會被flush或disable。兩者的區別在於,flush用於清空connection
pool中的所有連接(通常都是中斷的connection),當pool狀態仍保持在running狀態,而對於后者,connection
pool將會變成suspend。前者對於客戶端而言,還可以從pool中reserve
connection,reserve時,weblogic會嘗試重現創建連接,如果創建連接成功,那么客戶端就可以拿到可用的連接。而對於一個處於suspend狀態,客戶端reserve
connection的請求會直接被拒絕,收到的異常如下:
weblogic.common.resourcepool.ResourceDisabledException:
Pool JDBC Data Source-0 is disabled, cannot allocate resources to
applications
一個被disable的connection
pool我們需要手工resume嗎?比如數據庫因為某些原因而突發關閉,數據庫恢復后,我們是否需要手工去resume這個pool?不需要,weblogic內部實現了連接池的自我健康檢查功能,對於disable的connection
pool,weblogic會每隔5秒鍾(DEFAULT_SCAN_UNIT)去做一次連接嘗試(嘗試創建一個物理連接,如果連接成功,那么這個連接會被直接放入連接池中,我們的問題就處在這兒),我們通過下面的復現過程來看看具體原因:
http://www.blogjava.net/fjin/archive/2009/08/29/292494.html