Redis-实现SpringBoot集成Redis多数据源

4,842 阅读2分钟

背景

​ 有些时候在一个项目里,由于业务问题,可能仅仅操作一个Redis数据源已经不能满足,比如某个运营系统,对接着多个不同的服务,处理数据时又不想通过远程调用,那只能增加一个数据源来解决问题,像MySQL的多数据源一样。

配置示例

这里连接池选用的是lettuce

redis:
  host: localhost
  port: 6379
  password: 123456
  timeout: 60000
  database: 10
  lettuce:
    pool:
      min-idle: 0
      max-idle: 10
      max-wait: -1
      max-active: 200
      time-between-eviction-runs: -1
redis-live:
  host: localhost
  port: 6379
  password: 123456
  database: 0

实现代码

关于序列化使用的是jackson

以下提供了创建RedisTemplate以及StringRedisTemplate

关于二者的区别:

  • 两者的关系是StringRedisTemplate继承RedisTemplate。

  • 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。

  • SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。

    StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。 RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

/**
 * <p>
 * RedisLettuce 连接实例配置
 * </p>
 *
 * @author zhengshangjin
 * @version 1.0.0
 * @since 1.0.0
 * created on 2020-04-23
 */
@Configuration
@EnableCaching
public class RedisLettuceConfig {

    /**
     * live数据源
     */
    @Value("${spring.redis-live.host}")
    private String redisLiveHost;

    @Value("${spring.redis-live.port}")
    private int redisLivePort;

    @Value("${spring.redis-live.password}")
    private String redisLivePass;

    @Value("${spring.redis-live.database}")
    private int redisLiveDb;

    /**
     * 公共配置
     */
    @Value("${spring.redis.timeout}")
    private long timeout;
  
    @Value("${spring.redis.lettuce.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.lettuce.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.lettuce.pool.max-active}")
    private int maxActive;

    @Value("${spring.redis.lettuce.pool.max-wait}")
    private int maxWait;

    /**
     * 装配 RedisTemplate
     * <p>
     * 这里根据默认连接配置 装配实例
     * </>
     *
     * @param redisConnectionFactory 默认
     * @return redisTemplate
     * @author zhengshangjin
     * created on 2020-04-23
     */
    @Bean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return createRedisTemplate(redisConnectionFactory);
    }

    /**
     * 装配 StringRedisTemplate
     * <p>
     * 这里根据默认连接配置 装配实例
     * </>
     * @param redisConnectionFactory 默认
     * @return StringRedisTemplate
     * @author zhengshangjin
     * created on 2020-04-23
     */
    @Bean(name = "stringRedisTemplate")
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return createStringRedisTemplate(redisConnectionFactory);
    }

    /**
     * 装配 Live数据源
     *
     * @return liveStringRedisTemplate
     * @author zhengshangjin
     * created on 2020-04-23
     */
    @Bean(name = "liveStringRedisTemplate")
    public StringRedisTemplate liveStringRedisTemplate() {
        return createStringRedisTemplate(redisLiveHost, redisLivePort, redisLivePass, redisLiveDb);
    }

    /**
     * 创建 RedisTemplate
     *
     * @param redisConnectionFactory redisConnectionFactory
     * @return RedisTemplate
     * @author zhengshangjin
     * created on 2020-04-23
     */
    public RedisTemplate<Object, Object> createRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

        Jackson2JsonRedisSerializer<?> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        serializer.setObjectMapper(objectMapper);

        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 创建 StringRedisTemplate
     *
     * @param redisConnectionFactory redisConnectionFactory
     * @return StringRedisTemplate
     * @author zhengshangjin
     * created on 2020-04-23
     */
    public StringRedisTemplate createStringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
        return stringRedisTemplate;
    }

    /**
     * 创建 StringRedisTemplate
     *
     * @param host     主机
     * @param port     端口
     * @param password 密码
     * @param database 库
     * @return StringRedisTemplate
     * @author zhengshangjin
     * created on 2020-04-23
     */
    public StringRedisTemplate createStringRedisTemplate(String host, int port, String password, int database) {
        // 基本配置
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName(host);
        configuration.setPort(port);
        configuration.setDatabase(database);
        if (ObjectUtils.isNotEmpty(password)) {
            RedisPassword redisPassword = RedisPassword.of(password);
            configuration.setPassword(redisPassword);
        }

        // 连接池通用配置
        GenericObjectPoolConfig<?> genericObjectPoolConfig = new GenericObjectPoolConfig<>();
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMinIdle(minIdle);
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);

        // Lettuce Pool
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();
        builder.poolConfig(genericObjectPoolConfig);
        builder.commandTimeout(Duration.ofSeconds(timeout));
        LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, builder.build());
        connectionFactory.afterPropertiesSet();

        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(connectionFactory);
        return stringRedisTemplate;
    }

}

注入使用

根据@Qualifier指定beanname来获取

@Autowired
@Qualifier("liveStringRedisTemplate")
public StringRedisTemplate stringRedisTemplate;