[英]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.