redis中 Could not get a resource from the pool 異常解決

來源:互聯網
上載者:User

在項目中使用redis做緩衝,當運行一段時間後就會出現如下錯誤:Could not get a resource from the pool,然後在看具體的異常資訊就是JedisPool中擷取不到jedis對象,也就是說串連池中沒有可用的jedis。

自己的第一反應就是把最大連結數(setMaxTotal)調大一些,剛開始設定了100、後來200、在後來2000都不行

然後上網一搜發現大家的回答也都是修改最大串連數,如下demo就是網上一篇部落格的解釋:

1、產生原因:用戶端去redis伺服器拿串連(代碼描述的是租用對象borrowObject)的時候,池中無可用串連,即池中所有串連被佔用,且在等待時候設定的逾時時間後還沒拿到時,報出此異常。

2、解決辦法:調整JedisPoolConfig中maxActive為適合自己系統的閥值。

<bean id="dataJedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">        [color=red]<property name="maxActive" value="5000"/>[/color]        <property name="maxIdle" value="5000"/>        <property name="maxWait" value="10000"/>        <property name="testOnBorrow" value="true"/></bean>
但這個自己也設定了,配置如下:

#最大使用中的物件數     redis.pool.maxTotal=1000    #最大能夠保持idel狀態的對象數      redis.pool.maxIdle=100  #最小能夠保持idel狀態的對象數   redis.pool.minIdle=50    #當池內沒有返回對象時,最大等待時間    redis.pool.maxWaitMillis=10000    #當調用borrow Object方法時,是否進行有效性檢查    redis.pool.testOnBorrow=true    #當調用return Object方法時,是否進行有效性檢查    redis.pool.testOnReturn=true  #“空閑連結”檢測線程,檢測的周期,毫秒數。如果為負值,表示不運行“檢測線程”。預設為-1.  redis.pool.timeBetweenEvictionRunsMillis=30000  #向調用者輸出“連結”對象時,是否檢測它的空閑逾時;  redis.pool.testWhileIdle=true  # 對於“空閑連結”檢測線程而言,每次檢測的連結資源的個數。預設為3.  redis.pool.numTestsPerEvictionRun=50  #表示一個對象至少停留在idle狀態的最短時間,然後才能被idle object evitor掃描並驅逐;這一項只有在timeBetweenEvictionRunsMillis大於0時才有意義MinEvictableIdleTimeMillis=60000#redis伺服器的IP    redis.ip=xxxxxx  #redis伺服器的Port    redis1.port=6379   
但是這樣設定後,當運行一段時候後還是會報同樣的錯誤,說句不愛聽的話最大連結數“1000”這個值真的不小,但還是錯誤,所以肯定不是這個值的原因。

後來在網上找到了一篇文章,文章中的jedis工具類中有三個方法,代碼如下:

public class JedisUtils {private static Log logger = LogFactory.getLog(JedisUtils.class);/** * 自動注入Redis串連執行個體對象線程池 */@Autowiredprivate JedisPool jedisPool;/** * 擷取Jedis對象 *  * @return */public synchronized Jedis getJedis() {Jedis jedis = null;if (jedisPool != null) {try {if (jedis == null) {jedis = jedisPool.getResource();}} catch (Exception e) {logger.error(e.getMessage(), e);}}return jedis;}/** * 回收Jedis對象資源 *  * @param jedis */public synchronized void returnResource(Jedis jedis) {if (jedis != null) {jedisPool.returnResource(jedis);}}/** * Jedis對象出異常的時候,回收Jedis對象資源 *  * @param jedis */public synchronized void returnBrokenResource(Jedis jedis) {if (jedis != null) {jedisPool.returnBrokenResource(jedis);}}}

有兩個回收方法發現沒,一個是正常結束時調用釋放jedis資源而另一個是在出現異常時調用釋放jedis資源。

業務類、方法代碼如下:

  Jedis jedis = jedisUtils.getJedis();          if(jedis == null){              throw new NullPointerException("Jedis is Null");          }          try{              long queueCurrValue = jedis.llen(messageQueueName);              if(queueCurrValue >= queueMaxSize){                  return addFlag;              }              String serizlizetValue = JSON.toJSONString(message);              if(StringUtils.isNotBlank(serizlizetValue)){                  long queueLength = jedis.lpush(messageQueueName, serizlizetValue);                   if(queueLength - queueCurrValue > 0){                      addFlag = true;                  }              }          }catch(Exception e){              jedisUtils.returnBrokenResource(jedis);              logger.error(e.getMessage(), e);          }finally{              jedisUtils.returnResource(jedis);          }  

看到沒在finally{} 代碼塊和 catch(){} 異常中都調用了相關方法,來釋放jedis資源,這樣就不會出現之前的那種異常了,當然最大連結數也不用設定那麼大,下面看看修改後的設定檔

#最大連結數MaxTotal=100#空閑時最大連結數MaxIdle=20#空閑最小MinIdle=8#連結最大等待時間 (毫秒)MaxWaitMillis=10000

就這值,再也沒出現擷取不到資源的的異常,問題解決了,所以問題不是最大連結數小了,而是沒有釋放資源,所以不管你設定多大的值都會出現異常而且消耗了大量的資源。

單我在項目中使用的時候有如下問題:

        // 釋放資源public synchronized void returnResource(Jedis jedis) {if (jedis != null) {pool.returnResource(jedis);}}// 出現異常釋放資源public synchronized void returnBrokenResource(Jedis jedis) {if (jedis != null) {pool.returnBrokenResource(jedis);}}

兩個方法 returnResource(jedis)、 和 returnBrokenResource(jedis) 都被畫了橫線即過時廢棄了,而還不知替換方法所以有知道的請指教,先謝謝了。


相關文章推薦:

http://www.codeweblog.com/redis%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA-%E9%85%8D%E7%BD%AE-%E5%8F%8Ajedis%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/

http://www.codeweblog.com/jedis%E8%BF%9E%E6%8E%A5%E6%B1%A0%E9%85%8D%E7%BD%AE/

http://www.codeweblog.com/jedis-returnresource%E4%BD%BF%E7%94%A8%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/

http://fengguang0051.iteye.com/blog/2237171

不過其中的兩篇文章也會比自己轉載做筆記的……






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.