与其他部门同时联调时,他们的redis缓存不一定是写在 db0库。而项目中默认的RedistTemplate只能读取db0。可考虑如下解决方式:
适用于缓存提供方不方便调整db的情况,最好还是让提供方直接写到默认缓存库
解决方案
1.引入maven依赖
redis.clients
jedis
2.9.0
2.nacos配置
redis: host: 192.168.100.xxx port: 6379 password: maxIdle: 10 minIdle: 5 timeout: 1000 # 可以指定多个,用“,”隔开,写在第一个的为defaultDB dbs: 0,1,2
3.代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPoolConfig;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Slf4j
public class RedisConfig {
@Value("${redis.host}")
private String hostName;
@Value("${redis.port}")
private int port;
@Value("${redis.password}")
private String passWord;
@Value("${redis.maxIdle}")
private int maxIdl;
@Value("${redis.minIdle}")
private int minIdl;
@Value("${redis.timeout}")
private int timeout;
@Value("#{'${redis.dbs}'.split(',')}")
private List dbs;
private int defaultDb;
private static Map redisTemplateMap = new HashMap<>();
@PostConstruct
public void initRedisTemp() throws Exception {
log.info("###### START 初始化 Redis 连接池 START ######");
defaultDb = dbs.get(0);
for (Integer db : dbs) {
log.info("###### 正在加载Redis-db-" + db + " ######");
redisTemplateMap.put(db, redisTemplateObject(db));
}
log.info("###### END 初始化 Redis 连接池 END ######");
}
private StringRedisTemplate redisTemplateObject(Integer dbIndex) throws Exception {
StringRedisTemplate redisTemplateObject = new StringRedisTemplate();
redisTemplateObject.setConnectionFactory(redisConnectionFactory(jedisPoolConfig(), dbIndex));
redisTemplateObject.afterPropertiesSet();
return redisTemplateObject;
}
private JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(maxIdl);
poolConfig.setMinIdle(minIdl);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
poolConfig.setNumTestsPerEvictionRun(10);
poolConfig.setTimeBetweenEvictionRunsMillis(60000);
// 当池内没有可用的连接时,最大等待时间
poolConfig.setMaxWaitMillis(10000);
// ------其他属性根据需要自行添加-------------
return poolConfig;
}
private RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig, int db) {
// 单机版jedis
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
// 设置redis服务器的host或者ip地址
redisStandaloneConfiguration.setHostName(hostName);
// 设置默认使用的数据库
redisStandaloneConfiguration.setDatabase(db);
// 设置密码
redisStandaloneConfiguration.setPassword(RedisPassword.of(passWord));
// 设置redis的服务的端口号
redisStandaloneConfiguration.setPort(port);
// 获得默认的连接池构造器
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
// 指定jedisPoolConifig来修改默认的连接池构造器
jpcb.poolConfig(jedisPoolConfig);
// 通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpcb.build();
// 单机配置 + 客户端配置 = jedis连接工厂
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
public StringRedisTemplate getRedisTemplateByDb(int db) {
return redisTemplateMap.get(db);
}
public StringRedisTemplate getRedisTemplate() {
return redisTemplateMap.get(defaultDb);
}
}
使用
@Autowired
RedisConfig redisConfig;
fun xx(){
//得到操作db0的连接(默认)
redisConfig.getRedisTemplate().xxx
//得到操作db2的连接
redisConfig.getRedisTemplateByDb(2).xxx
}
优缺点
缺点:目前只支持单机
优点:可配置,为每个库建立连接,并发时产生切换的开销小



