1. 程式人生 > >Jedis “Socket讀取超時”導致“返回值型別錯誤”

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讀取超時異常

",具體異常資訊"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裡還殘存著上次沒有傳送或者傳送不完整的命令。這個時候沒有做處理,直接將該連線返回到連線池,那麼重用該連線執行下次命令的時候,就會將上次沒有傳送的命令一起傳送過去,所以才會出現上面的錯誤“返回值型別不對”

所以,正確的寫法應該是:在傳送異常的時候,銷燬這個連線,不能再重用! 

參考自: