遇到過這樣一個嚴重問題:
發布的項目不知從什么時候開始,每月會出現一兩次串號問題。串號現象指的是,用戶用賬號A登錄系統,然后某個時間,登錄賬號自動變成了B。
串號出現的時間不定,測試平台難以重現,且后台檢測不到錯誤,難以定位。當時各種排查,最后發現問題果然是出在緩存redis上,JedisPool使用有問題。
JedisPool使用注意事項:
1、每次從pool獲取資源后,一定要try-finally釋放,否則會出現很多莫名其妙的錯誤。
2、資源釋放不能一致使用returnBrokenResource【項目問題就出在第二條注意事項上】。
相關代碼
代碼修改前大致如下:
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);
}
}
}
相關源碼:
分析源代碼,可以知道本來應該執行returnBrokenResourceObject方法,結果卻執行了returnResourceObject,並且執行returnResourceObject過程中沒有報錯。
具體原因應該就在方法體里面,可惜點進去並沒有分析出具體是哪幾行代碼導致了串號的出現 = =!
不過當時項目return方面進行了修改后,錯誤確實沒有再出現。
下面這篇文章也講解了returnSource的相關注意事項,大家可以參考下
http://www.codeweblog.com/jedis-returnresource使用注意事項/
PS:當時項目使用的是Jedis2.7.0,不用通過圖片1可以發現Jedis3.0后,returnResource就不使用了,建議用close替換。
即:jedisPool.returnResource(jedis) ---> jedis.close();