千家信息网

SpringBoot集成Redis引起的序列化问题怎么解决

发表于:2024-11-20 作者:千家信息网编辑
千家信息网最后更新 2024年11月20日,这篇文章主要讲解了"SpringBoot集成Redis引起的序列化问题怎么解决",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"SpringBoot集成R
千家信息网最后更新 2024年11月20日SpringBoot集成Redis引起的序列化问题怎么解决

这篇文章主要讲解了"SpringBoot集成Redis引起的序列化问题怎么解决",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"SpringBoot集成Redis引起的序列化问题怎么解决"吧!

想必大家对SpringBoot可能已经很熟悉了,包括集成Redis这种常用的技术,之前一直用一贯的写法去集成Redis,写配置类没发现过任何问题,但是上周在给Redis配置类加了一个Bean之后就出现了很难发现的问题。

配置类代码 `@Configuration public class RedisConfig extends CachingConfigurerSupport {

[@Bean](https://my.oschina.net/bean)public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {    RedisTemplate redisTemplate = new RedisTemplate<>();    redisTemplate.setConnectionFactory(redisConnectionFactory);    // 使用Jackson2JsonRedisSerialize 替换默认序列化    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);    ObjectMapper objectMapper = new ObjectMapper();    objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);    jackson2JsonRedisSerializer.setObjectMapper(objectMapper);    // 设置value的序列化规则和 key的序列化规则    redisTemplate.setKeySerializer(new StringRedisSerializer());    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);    redisTemplate.setHashKeySerializer(new StringRedisSerializer());    redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);    redisTemplate.afterPropertiesSet();    return redisTemplate;}[@Bean](https://my.oschina.net/bean)public CacheManager cacheManager(RedisConnectionFactory factory) {    RedisSerializer redisSerializer = new StringRedisSerializer();    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);    //解决查询缓存转换异常的问题    ObjectMapper om = new ObjectMapper();    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);    jackson2JsonRedisSerializer.setObjectMapper(om);    // 配置序列化(解决乱码的问题),过期时间30秒    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()            .entryTtl(Duration.ofSeconds(1800000))            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))            .disableCachingNullValues();    RedisCacheManager cacheManager = RedisCacheManager.builder(factory)            .cacheDefaults(config)            .build();    return cacheManager;}

}` 也就是增加了cacheManager()这个方法之后,数据量小的时候是没有任何问题的,但是一旦放到线上,数据量一上来,那么整个Redis就导致内存溢出,整个服务都会挂掉。

错误日志: 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.lang.OutOfMemoryError: Java heap space at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:84) ~[spring-data-redis-2.1.6.RELEASE.jar!/:2.1.6.RELEASE] at org.springframework.session.data.redis.RedisOperationsSessionRepository.onMessage(RedisOperationsSessionRepository.java:538) ~[spring-session-data-redis-2.1.5.RELEASE.jar!/:2.1.5.RELEASE] at org.springframework.data.redis.listener.RedisMessageListenerContainer.executeListener(RedisMessageListenerContainer.java:250) [spring-data-redis-2.1.6.RELEASE.jar!/:2.1.6.RELEASE] at org.springframework.data.redis.listener.RedisMessageListenerContainer.processMessage(RedisMessageListenerContainer.java:240) [spring-data-redis-2.1.6.RELEASE.jar!/:2.1.6.RELEASE] at org.springframework.data.redis.listener.RedisMessageListenerContainer.lambda$dispatchMessage$0(RedisMessageListenerContainer.java:986) [spring-data-redis-2.1.6.RELEASE.jar!/:2.1.6.RELEASE] at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_191] Caused by: 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.lang.OutOfMemoryError: Java heap space at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78) ~[spring-core-5.1.6.RELEASE.jar!/:5.1.6.RELEASE] at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36) ~[spring-core-5.1.6.RELEASE.jar!/:5.1.6.RELEASE] at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:82) ~[spring-data-redis-2.1.6.RELEASE.jar!/:2.1.6.RELEASE] ... 5 common frames omitted Caused by: java.lang.OutOfMemoryError: Java heap space

至于为什么注入这个bean之后会出现这个问题,去了这个bean之后,不会再出现这个问题,目前我还没找到原因,分享出来大家一起参考,避免在网上找的配置应用在自己的代码中出现问题,也欢迎踩过坑的朋友来解答。

感谢各位的阅读,以上就是"SpringBoot集成Redis引起的序列化问题怎么解决"的内容了,经过本文的学习后,相信大家对SpringBoot集成Redis引起的序列化问题怎么解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0