关于spring boot2以上的redis多库使用踩坑
Posted 摩尔迦娜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于spring boot2以上的redis多库使用踩坑相关的知识,希望对你有一定的参考价值。
最近项目跟其他公司合作,登录用户使用他们的接口,用户信息放在一个9号db的redis里使用,本身项目也用了redis,使用的是0号db。
最开始想的是在代码里面手动切换,用一个redisTemplate,找来找去发现网上说2.0以上是这么切换redis的
Optional.ofNullable((LettuceConnectionFactory) redisTemplate.getConnectionFactory()) .ifPresent( factory -> { factory.setDatabase(9);
redisTemplate.setConnectionFactory(factory);
factory.resetConnection();
}
);
放到代码里发现,怎么切换插入的都是0 db里面,坑爹啊,有的说换redis依赖版本就行了,但有篇文章说了是resetConection()并没有真正的按新的设置初始化redis,按照上边加了一条语句
Optional.ofNullable((LettuceConnectionFactory) redisTemplate.getConnectionFactory()) .ifPresent( factory -> { factory.setDatabase(9);
redisTemplate.setConnectionFactory(factory);
factory.resetConnection();
factory.afterPropertiesSet();//按新的设置初始化
}
);
然后代码里测试了下,果然切换成功了,但真的没问题了么?
这时候又在其他类里使用redisTemplate,发现怎么操作的也是9 db?
这怎么行,不可能每次切换后,还得切换回来吧,而且要是同时的并发操作,也会在切换过程中造成其他的提交失败,这个方案只能废弃。
这时想到,一个实例不行,那就实例化二个不就行了,每个对应分别各自的db,这样也不会操作冲突。
@Configuration @ConfigurationProperties(prefix = "spring.redis.other", ignoreInvalidFields = true) @Data @RefreshScope public class RedisTemplateConfig { @Resource private final RedisConnectionFactory redisConnectionFactory; private String host = "127.0.0.1"; private String password = null; private Integer port =6367; private Integer database = 9; @Bean public RedisTemplate<String, Object> redisOtherTemplate() { /* ========= 基本配置 ========= */ RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(); configuration.setHostName(host); configuration.setPort(port); configuration.setDatabase(database); if (!ObjectUtils.isEmpty(password)) { RedisPassword redisPassword = RedisPassword.of(password); configuration.setPassword(redisPassword); } /* ========= 连接池通用配置 ========= */ GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); genericObjectPoolConfig.setMaxTotal(20); genericObjectPoolConfig.setMinIdle(0); genericObjectPoolConfig.setMaxIdle(10); genericObjectPoolConfig.setMaxWaitMillis(-1); /* ========= lettuce pool ========= */ LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder(); builder.poolConfig(genericObjectPoolConfig); builder.commandTimeout(Duration.ofSeconds(2000)); LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, builder.build()); connectionFactory.afterPropertiesSet(); /* ========= 创建 template ========= */ return createRedisTemplate(connectionFactory); } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; } public RedisTemplate<String, Object> createRedisTemplate(RedisConnectionFactory newFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setConnectionFactory(newFactory); return redisTemplate; }
}
分别注入使用就可以了
@Component @AllArgsConstructor public class InitCacheRunner implements ApplicationRunner { private final RedisTemplate redisTemplate; private final RedisTemplate redisOtherTemplate; }
最后读取其他公司的redis内容时,又出现个问题 cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException
这个是因为对面存的时候,设置的序列化跟我取的时候序列化方式不一样,会出现这个错误,
在初始化redis的时候设置下对方序列化的方式就行了
redisTemplate.setValueSerializer(new GenericToStringSerializer<String>(String.class));
大功告成,如果以后出问题再回来记下吧
以上是关于关于spring boot2以上的redis多库使用踩坑的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot2.X 自定义Redis的cacheManager,保存Json格式到Redis