ShardedJedisPool 中可用连接数的小bug
ShardedJedisPool中,returnBrokenResource() 及 returnResource() ,為施放資源、關閉連接的方法,若重復調用,導致 _numActive 當前活動數一直遞減,會出現負數的情況。
假如在一個方法中設置了三個jedis連接,在獲取第一或第二個連接時出現異常,在拋出異常或者finally中總是施放這三個資源,會導致池中的連接連續施放三次,從而變成負數。
這樣會出現連接池最大連接數配置無效的情況。
?
以下片段代碼:
public class RedisUtil {public static ShardedJedisPool pool;static {JedisPoolConfig config = new JedisPoolConfig();// Jedis池配置config.setMaxActive(2);// 最大活動的對象個數config.setMaxIdle(1000 * 60);// 對象最大空閑時間config.setMaxWait(1000 * 3);// 獲取對象時最大等待時間config.setTestOnBorrow(true);String hostA = "192.168.0.99";int portA = 6380;List<JedisShardInfo> jdsInfoList =new ArrayList<JedisShardInfo>(1);JedisShardInfo infoA = new JedisShardInfo(hostA, portA);jdsInfoList.add(infoA);pool = new ShardedJedisPool(config, jdsInfoList);}public static void testRedis() {ShardedJedis jedis = null;ShardedJedis jedis1 = null;ShardedJedis jedis2 = null;try {// 從池中獲取三次連接jedis = pool.getResource();jedis1 = pool.getResource();jedis2 = pool.getResource();String value = jedis.get("wuse");String value1 = jedis1.get("wuse");if (null == value || "".equals(value)) {jedis.set("wuse", "testWuse");jedis.expire("wuse", 20);}else {System.out.println(value);}} catch (Exception e) {e.printStackTrace();// 異常時關閉連接,此處可以注釋} finally {pool.returnBrokenResource(jedis);pool.returnBrokenResource(jedis1);pool.returnBrokenResource(jedis2);}} }?
比如,設置的最大連接數為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,有可能最終導致負數(其實是與實際活動數不匹配),從而影響到原始設定的最大連接數會不管用。
?
?
?
轉載于:https://www.cnblogs.com/anranwuse/p/3698052.html
總結
以上是生活随笔為你收集整理的ShardedJedisPool 中可用连接数的小bug的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海量数据处理分析(部分)
- 下一篇: 柯乐义猜数字游戏