java----記錄jedispool的一個坑 jedispool導致線程阻塞

背景

一個多線程的消費任務,從kafka讀數據放到LinkedBlockingQueue,另一個線程消費此鏈表數據。
在消費的時候本意期望用redis實現一個鎖。
java中有對應的包jedisLock。
從Jedispool中獲取一個連接去進行redis操作。

代碼

		Jedis jedis = jedisPool.getResource();
        JedisLock lock = new JedisLock(jedis, key, 10000, 30000);
        try {
            lock.acquire();
			//
        } catch (Exception e) {
            logger.error("redis connect failed");
            logger.error(e.getMessage());
            }
        } finally {
            lock.release();
        }

現象

在測試環境沒有問題。
在線上消費一段時間就停止消費。程序處於假死狀態。
而且有些時候很長時間不會假死,有些時候一會就會假死。
於是開始排查。

日誌

開始消費正常。之後線程開始sleep。程序卡死狀態。在這裏插入圖片描述

jedis源碼分析

爲了追蹤這個數目,設置了一個變量sum,消費一條數據sum++,發現每次都是消費1024個就開始阻塞。
繼續跟蹤,發現在jedispool獲取資源的時候阻塞,也即獲取不到資源,阻塞住在獲取資源處。
在這裏插入圖片描述
redis配置爲最大連接數1024個。
開始思考,爲什麼獲取不到資源不會拋異常,會阻塞,進而去看Jedis源碼。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
maxWaitMillis默認爲-1。
繼續追進代碼。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
到這裏,線程就鎖住了,獲取不到資源。
這時候,我又有一個問題,爲什麼之前的redis資源不會自己釋放呢,之前用線程池的時候,會自己回收,爲什麼jedisPool沒有。必須要手動jedis.close,我去看jedis.close的代碼。
在這裏插入圖片描述

結論

1.在使用jedispool的時候一定要注意資源的釋放。
2.一定要注意maxWaitMillis的設置。
否則會出現阻塞的問題。一定注意!!!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章