遇到過這樣一個嚴重問題:
發佈的項目不知從何時開始,每個月會出現一兩次串號問題。串號現象指的是,用戶用帳號A登陸系統,而後某個時間,登陸帳號自動變成了B。
串號出現的時間不定,測試平臺難以重現,且後臺檢測不到錯誤,難以定位。當時各類排查,最後發現問題果真是出在緩存redis上,JedisPool使用有問題。web
一、每次從pool獲取資源後,必定要try-finally釋放,不然會出現不少莫名其妙的錯誤。
二、資源釋放不能一導致用returnBrokenResource【項目問題就出在第二條注意事項上】。redis
代碼修改前大體以下:緩存
public void closeResource(Jedis jedis) { if (null != jedis) { jedisPool.returnResource(jedis); } }
代碼修改後大體以下【isOK正常設爲true,捕獲到異常如JedisConnectionException時傳入false】:測試
public void closeResource(Jedis jedis, boolean isOK) { if (null != jedis) { if(!isOK){ LOG.error("do some things.."); jedisPool.returnBrokenResource(jedis); }else{ jedisPool.returnResource(jedis); } } }
相關源碼:code
分析源代碼,能夠知道原本應該執行returnBrokenResourceObject方法,結果卻執行了returnResourceObject,而且執行returnResourceObject過程當中沒有報錯。blog
具體緣由應該就在方法體裏面,惋惜點進去並無分析出具體是哪幾行代碼致使了串號的出現 = =!
不過當時項目return方面進行了修改後,錯誤確實沒有再出現。圖片
下面這篇文章也講解了returnSource的相關注意事項,你們能夠參考下
http://www.codeweblog.com/jedis-returnresource使用注意事項/資源
PS:當時項目使用的是Jedis2.7.0,不用經過圖片1能夠發現Jedis3.0後,returnResource就不使用了,建議用close替換。
即:jedisPool.returnResource(jedis) ---> jedis.close();get