天天看點

ShardedJedisPool 中可用連接配接數的小bug

shardedjedispool中,returnbrokenresource() 及 returnresource()

,為施放資源、關閉連接配接的方法,若重複調用,導緻 _numactive 目前活動數一直遞減,會出現負數的情況。

假如在一個方法中設定了三個jedis連接配接,在擷取第一或第二個連接配接時出現異常,在抛出異常或者finally中總是施放這三個資源,會導緻池中的連接配接連續施放三次,進而變成負數。

這樣會出現連接配接池最大連接配接數配置無效的情況。

以下片段代碼:

比如,設定的最大連接配接數為3,當第一次擷取連接配接1和連接配接2的時候,沒有問題,擷取第三個連接配接的時候,由于最大連接配接數為2,是以抛異常

走finally之後,釋放掉三個連接配接資源,這時候,pool連接配接池的目前活動數竟然為-1

是以,第二次再調用testredis()方法時,由于之前pool的活動數為-1,這次三個連接配接都能擷取成功,不抛異常。

-------------------------------------------------------------------------------

shardedjedispool類本身繼承pool類,pool類中用了org.apache.commons.pool.impl.genericobjectpool類來當做連接配接池,而pool類初始化時,需要傳入poolableobjectfactory工廠類,在shardedjedispool類中自定義了一個繼承basepoolableobjectfactory類的工廠類shardedjedisfactory,而shardedjedisfactory類中的銷毀方法destroyobject()方法中,從傳進來的shardedjedis對象裡擷取了鏡像連接配接,繼承的最頂層sharded類中的getallshards()方法,實際上隻是通過collections工具類擷取了resources的value集合的鏡像,是以實際上也就是說隻是意義上釋放了連接配接。 

而shardedjedispool類中的returnbrokenresource()方法,實際上調用的是genericobjectpool類的invalidateobject()方法,而每次調用後,總會再去做 _numactive

--,也就是說,每次調用,目前活動數都會減1,有可能最終導緻負數(其實是與實際活動數不比對),進而影響到原始設定的最大連接配接數會不管用。