码迷,mamicode.com
首页 > 编程语言 > 详细

关于spring boot2以上的redis多库使用踩坑

时间:2020-07-08 13:40:35      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:cannot   sse   踩坑   actor   stand   ict   nec   public   pre   

最近项目跟其他公司合作,登录用户使用他们的接口,用户信息放在一个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多库使用踩坑

标签:cannot   sse   踩坑   actor   stand   ict   nec   public   pre   

原文地址:https://www.cnblogs.com/moerjiana/p/13266244.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!