springboot2.X 连接多个Redis数据源

本文介绍如何在Spring Boot项目中配置并使用两套独立的Redis数据源,包括pom依赖、application.properties配置、自定义Redis配置类及在业务中进行数据源选择的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:我们测试环境有两套,所以涉及俩套Redis存储,测试环境存储订单被锁的情况,解锁的话需要手动在对应的Redis DB中删除订单号key。为节省人工,考虑才测试平台做一个简单的功能,查询订单是否被锁,解锁(即删除订单号)

pom

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.properties

#redis数据源1 默认 第一套环境
# Redis 数据库索引(默认为 0)
spring.redis.database=0
# Redis 服务器地址
spring.redis.host=***.***.**.**
# Redis 服务器连接端口
spring.redis.port=5***  
# Redis 服务器连接密码(默认为空)
spring.redis.password=0e17ba8627cd8f91
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0
#redis数据源2 第二套环境
# Redis 数据库索引(默认为 0)
spring.redis2.database=0
# Redis 服务器地址
spring.redis2.host=**.**.**.**
spring.redis2.port=5***  
# Redis 服务器连接密码(默认为空)
spring.redis2.password=283f90d469434509

自定

义config实现数据源的加载

package com.jrqa.riskpushvariabletestserver.configredis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

/**
 * by zfy
 * 2019/5/6
 */
@Configuration
@EnableCaching
public class RedisConfigMain extends CachingConfigurerSupport {
    /**
     * 配置lettuce连接池
     *
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
    public GenericObjectPoolConfig redisPool() {
        return new GenericObjectPoolConfig<>();
    }

    /**
     * 配置第一个数据源的
     *
     * @return
     */
    @Bean
//    @ConfigurationProperties(prefix = "spring.redis")
    public RedisStandaloneConfiguration redisConfig(@Value("${spring.redis.host}") String host, @Value("${spring.redis.port}") int port
                                                    , @Value("${spring.redis.database}") int db, @Value("${spring.redis.password}") String password) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port);
        redisStandaloneConfiguration.setDatabase(db);
        redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
        return redisStandaloneConfiguration;
    }

    /**
     * 配置第二个数据源
     *
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.redis2")
    public RedisStandaloneConfiguration redisConfig2() {
        return new RedisStandaloneConfiguration();
    }

    /**
     * 配置第一个数据源的连接工厂
     * 这里注意:需要添加@Primary 指定bean的名称,目的是为了创建两个不同名称的LettuceConnectionFactory
     *
     * @param config
     * @param redisConfig
     * @return
     */
    @Bean("factory")
    @Primary
    public LettuceConnectionFactory factory(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfig) {
        LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(config).build();
        return new LettuceConnectionFactory(redisConfig, clientConfiguration);
    }

    @Bean("factory2")
    public LettuceConnectionFactory factory2(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfig2) {
        LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(config).build();
        return new LettuceConnectionFactory(redisConfig2, clientConfiguration);
    }

    /**
     * 配置第一个数据源的RedisTemplate
     * 注意:这里指定使用名称=factory 的 RedisConnectionFactory
     * 并且标识第一个数据源是默认数据源 @Primary
     *
     * @param factory
     * @return
     */
    @Bean("redisTemplate")
    @Primary
    public RedisTemplate<String, String> redisTemplate(@Qualifier("factory") RedisConnectionFactory factory) {
        return getStringStringRedisTemplate(factory);
    }

    /**
     * 配置第一个数据源的RedisTemplate
     * 注意:这里指定使用名称=factory2 的 RedisConnectionFactory
     *
     * @param factory2
     * @return
     */
    @Bean("redisTemplate2")
    public RedisTemplate<String, String> redisTemplate2(@Qualifier("factory2") RedisConnectionFactory factory2) {
        return getStringStringRedisTemplate(factory2);
    }

    /**
     * 设置序列化方式 (这一步不是必须的)
     *
     * @param factory
     * @return
     */
    private RedisTemplate<String, String> getStringStringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        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);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

}

 

config数据加载代码参看

RedisStandaloneConfiguration的源码,因为刚开始我只用的注解
//    @ConfigurationProperties(prefix = "spring.redis")

但是仅使用这行注解端口是取对了的,但是host取得默认值localhost,说明这用使用是不对的。参看源码后,使用以上实现方式ok。

 

使用

package com.jrqa.riskpushvariabletestserver.service.impl;

import com.jrqa.riskpushvariabletestserver.service.RiskOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * by zfy
 * 2019/5/5
 */
@Service
public class RiskOrderServiceImpl implements RiskOrderService {

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate firstRedisTemplate;

    @Autowired
    @Qualifier("redisTemplate2")
    private RedisTemplate secondRedisTemplate;


    public boolean exists(String key) {
        return firstRedisTemplate.hasKey(key);
    }

    public boolean remove(final String key) {
        if (exists(key)) {
            return firstRedisTemplate.delete(key);
        }else {
            return false;
        }
    }

    @Override
    public boolean exists(String key, String num) {
        if ("1".equals(num)){
            return firstRedisTemplate.hasKey(key);
        }else if ("2".equals(num)){
            return secondRedisTemplate.hasKey(key);
        }
        return false;
    }

    @Override
    public boolean remove(String key, String num) {
        boolean exists = exists(key, num);
        if("1".equals(num) && exists){
            return firstRedisTemplate.delete(key);
        }else if ("2".equals(num) && exists){
            return secondRedisTemplate.delete(key);
        }
        return false;
    }
}

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值