前兩天項目上線的時候遇到了redis的一個問題,在測試環境的時候項目運行正常,項目一上線redis便開始拋異常。java
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at
…
Caused by: java.util.NoSuchElementException: Unable to validate object at
看日誌發現是池的鏈接不夠,可是項目的調用量徹底在預算以內。網上說有RDB持久化的問題,也有說是配置了 redisTestOnBorrow致使檢查的時候鏈接不經過。可是通過排查都不是。後來去業務代碼中去尋找問題、
發現這段代碼public boolean remove(final String key) { try {…
final byte[] rawKey = SerializerUtil.rawKey(key);
if (!this.containsKey(key)) {
return true;
}
Long size = (Long) this.redisTemplate.execute(
new RedisCallback<Object> () {
public Object doInRedis(RedisConnection connection) {
connection.select(chooseDb(key));
Long size = connection.del(rawKey);
return size;
}
}, true);
return size > 0 ? true : false;
} catch (Exception e) {
LOGGER.error(ERROR_MESSAGE, e);
throw new CacheException(ServiceConstants.SERVICE_SYSTEM_FALIURE, e);
}
}
請看標紅處,每次都會選擇到對應的redis庫,由於測試環境的redis數據庫是單機的,線上的事分佈式的數據庫,並且咱們是Twemproxy,用一致性Hash算法,因此每次切數據庫去找的時候就會找不到鏈接
。
這裏把問題記錄下來,你們之後在排查問題的時候必定要把異常與業務相結合,這樣才能找到本身的真正問題。