"Could not get a resource from the pool org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool" 和 "Connect timed out」
複製代碼
由於我我的的能力和精力有限,若是有任何不對或者須要完善的地方,請幫忙指出!java
《記錄Redis事故影響API性能-上篇》 這篇文章中解決方法中第一個想到的是和運維確認redis 問題和拋出了若是咱們哨兵模式當中若是一個節點掛掉會不會出現 獲取不到鏈接池和超時呢?redis
咱們先來分析一下節點掛掉會不會出現問題,我經過分析jedis 源碼 答案是 即便掛掉一個節點不會出現鏈接池獲取不到和超時,下面咱們一步一步來分析:spring
第一步:咱們的redis 環境是基於哨兵模式,因此咱們只看JedisSentinelPool 這個類文件就能夠了,先看鏈接哨兵的初始化邏輯。架構
第二步:咱們從源碼中能夠看到在初始化哨兵節點啓了一個線程來作監聽的,下面咱們看看這塊的源碼運維
我縮了一下代碼,總體看一下這個內部類 MasterListener 源碼微服務
在看一下run 方法 具體實現post
好,你們仔細看一下咱們第二步的兩個截圖,咱們經過假設論證的方法來論證咱們的假設是否成立。性能
假設個人三個哨兵節點,其中有一個節點掛掉了,會影響服務而且報timeout 和 獲取不到鏈接池資源,但經過咱們查看源碼 這個假設一眼就看的出來 拋出的Exception 和咱們的假設步一致,若是是某一個節點掛掉了會報 下面Excetpion 中的一種,因此假設不成立學習
if (running.get()) {
log.log(Level.SEVERE, "Lost connection to Sentinel at " + host + ":" + port
+ ". Sleeping 5000ms and retrying.", e);
try {
Thread.sleep(subscribeRetryWaitTimeMillis);
} catch (InterruptedException e1) {
log.log(Level.SEVERE, "Sleep interrupted: ", e1);
}
} else {
log.fine("Unsubscribing from Sentinel at " + host + ":" + port);
}
複製代碼
咱們在找運維的時候,運維也不肯定Redis 是否有問題,就重啓了一個哨兵節點,應用報了一個錯誤 而後瞬間就行了,好的當時截圖留了一個證據,如今分析來看 這個錯誤日誌能給我很大的啓示可是咱們錯過了,若是你對jedis 有深刻的瞭解的話。spa
"Could not get a resource from the pool org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool"
複製代碼
"Could not get a resource from the pool org.springframework.data.redis.RedisConnectionFailureException: Connect timed out; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Connect timed out"
複製代碼
對於如何定位線上問題和能準確並快速肯定問題的根因的方法論和原則
做者:易企秀工程師 henry_chen