簡體   English   中英

Spring 數據 Redis 與生菜的反序列化問題

[英]Deserializing issue with Spring Data Redis with Lettuce

環境:
艾克斯 7.1
redis 2.6.17
JDK 1.6
spring-data-commons-1.12.11.RELEASE
spring-data-keyvalue-1.1.11.RELEASE
spring-data-redis-1.7.11
lettuce-3.5.0.Final
Redis 服務器與 web 應用程序(Redis 的客戶端)在同一主機上運行

問題:
我設置了以下 RedisTemplate Bean 配置:

@Bean
public RedisTemplate<String, Object> redisTemplate() {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
    redisTemplate.setConnectionFactory(redisConnectionFactory());
    redisTemplate.setEnableTransactionSupport(true);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.sethashKeySerializer(new StringRedisSerializer);
    return redisTemplate;
}

以下是 Redis 服務器的驗證檢查器代碼:

public class ObservableRedisStateChecker implements Runnable {
    ...
    public void run() {
       try {
           Thread.sleep(3000);
           redisTemplate.opfForValue().get("validation");
           notifyObservers(true);
       } catch (Exception e) {
           noifyObservers(false);  // meaning that the Redis' state isn't fine.
       }
    ...
}

上述 ObservableRedisStateChecker 會定期檢查並通知其他實例 Redis 服務器的 state。 該代碼通常可以正常工作,但是當發出的請求過多時,會出現以下錯誤:

org.springframework.data.redis.serializer.SerializationException: 
Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: 
Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; 
nested exception is java.io.EOFException

一個奇怪的點是,當我啟動一個簡單的測試應用程序,它在同一主機上運行與上述驗證代碼完全相同的代碼時,會發生錯誤,而當錯誤發生時,測試應用程序會說沒有錯誤。 該錯誤剛剛發生在 web 應用程序上。
測試代碼如下:

...
ExecutorService es = Executors.newCachedThreadPool()
RedisTemplate<String, Obejct> redisTemplate = ...

es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
es.submit(new RedisValidationCheckTest(redisTemplate));
...

它出什么問題了?

這似乎是一個序列化問題。

您沒有為您的值設置反序列化器。 所以redis使用的是默認的serializaer:JdkSerializationRedisSerializer,一點都不好。 我建議使用 Jackson,或者只是一個 StringRedisSerializer。

可能由於網絡問題,它收到了一些不完整的響應,並且 jdk 反序列化器無法識別它並抱怨。 將此添加到您的配置中

redisTemplate.setValueSerializer(new StringRedisSerializer());

另外,我建議您將代碼從

redisTemplate.opfForValue().get("驗證");

redisTemplate.getConnectionFactory().getConnection().ping()

因為后者是為了驗證。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM