日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ShardedJedisPool 中可用连接数的小bug

發布時間:2023/12/10 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。