Jedis “Socket讀取超時”導致“返回值型別錯誤”
從異常資訊來看,首先是在'zadd'操作時出現"Socket讀取超時異常",具體異常資訊"JedisConnectionException: java.net.SocketTimeoutException: Read timed out"。
出現異常後,會銷燬這個阻塞的Jedis連線池物件(CustomShardedJedisPool.returnBrokenResource(CustomShardedJedisPool.java:121)),但在請求Redis服務端關閉連線時,出現"強制型別轉換異常",具體異常資訊"ClassCastException: java.lang.Long
cannot be cast to [B
這個問題已經有前輩遇到過了,其解釋:
檢視 Jedis 原始碼發現它的Connection中對網路輸出流做了一個封裝(RedisInputStream),其中自建了一個buffer。當發生異常的時候,這個buffer裡還殘存著上次沒有傳送或者傳送不完整的命令。這個時候沒有做處理,直接將該連線返回到連線池,那麼重用該連線執行下次命令的時候,就會將上次沒有傳送的命令一起傳送過去,所以才會出現上面的錯誤“返回值型別不對”。
所以,正確的寫法應該是:在傳送異常的時候,銷燬這個連線,不能再重用!
參考自:
從異常資訊來看,首先是在'zadd'操作時出現"Socket讀取超時異常
出現異常後,會銷燬這個阻塞的Jedis連線池物件(CustomShardedJedisPool.returnBrokenResource(CustomShardedJedisPool.java:121)),但在請求Redis服務端關閉連線時,出現"強制型別轉換異常",具體異常資訊"ClassCastException: java.lang.Long cannot be cast to [B"。
這個問題已經有前輩遇到過了,其解釋:
檢視 Jedis 原始碼發現它的Connection中對網路輸出流做了一個封裝(RedisInputStream),其中自建了一個buffer。當發生異常的時候,這個buffer裡還殘存著上次沒有傳送或者傳送不完整的命令。這個時候沒有做處理,直接將該連線返回到連線池,那麼重用該連線執行下次命令的時候,就會將上次沒有傳送的命令一起傳送過去,所以才會出現上面的錯誤“返回值型別不對”。
所以,正確的寫法應該是:在傳送異常的時候,銷燬這個連線,不能再重用!
參考自: