一:需求背景
根据application.yml里面的内容,java代码自动实现单机和哨兵模式的兼容
比如如果是下面这种配置,则实现单机配置:
spring:
redis:
cluster:
nodes: 127.0.0.1:6379
password: "xxxx"
timeout: 6000
database: 0
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
sentinel:
master: mymaster
nodes: 127.0.0.1:6379
比如如果是下面这种配置,则实现哨兵配置:
spring
redis:
cluster:
nodes: 127.0.0.1:8881,127.0.0.1:8882,127.0.0.1:8883
password: "xxxx"
timeout: 6000
database: 0
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
sentinel:
master: mymaster
nodes: 127.0.0.1:18881,127.0.0.1:18882,127.0.0.1:18883
二:Redis代码
@Configuration
public class RedisConfiguration {
@Value("${spring.redis.sentinel.nodes}")
private String cluster;
@Bean
@Primary
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
@Bean
public RedisConnectionFactory lettuceConnectionFactory(RedisProperties redisProperties) {
String[] hostAndPorts = cluster.split(",");
if (hostAndPorts.length == 1) {
String host = hostAndPorts[0].split(":")[0];
int port = Integer.valueOf(hostAndPorts[0].split(":")[1]);
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
RedisStandaloneConfiguration rsc = connectionFactory.getStandaloneConfiguration();
rsc.setHostName(host);
rsc.setPort(port);
return connectionFactory;
} else {
// 配置哨兵节点以及主节点
RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration(
redisProperties.getSentinel().getMaster(), new HashSet<>(redisProperties.getSentinel().getNodes())
);
LettucePoolingClientConfiguration lettuceClientConfiguration = LettucePoolingClientConfiguration.builder()
.readFrom(ReadFrom.REPLICA_PREFERRED)
.build();
return new LettuceConnectionFactory(redisSentinelConfiguration, lettuceClientConfiguration);
}
}
}
三:Redisson代码
@Configuration
@Component
public class RedissionConfig {
@Value("${spring.redis.sentinel.master}")
private String master;
@Value("${spring.redis.sentinel.nodes}")
private String cluster;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private Integer timeout;
@Bean
public Redisson redisson() {
String[] hostAndPorts = cluster.split(",");
Config config = new Config();
if(hostAndPorts.length==1){
String host = hostAndPorts[0].split(":")[0];
int port = Integer.valueOf(hostAndPorts[0].split(":")[1]);
config.setCodec(new JsonJacksonCodec());
config.useSingleServer().
setAddress("redis://" + host + ":" + port);
}else {
List<String> clusterNodes = new ArrayList<>();
for (int i = 0; i < hostAndPorts.length; i++) {
clusterNodes.add("redis://" + hostAndPorts[i]);
}
SentinelServersConfig serverConfig = config.useSentinelServers()
.addSentinelAddress(clusterNodes.toArray(new String[0]))
.setMasterName(master)
.setReadMode(ReadMode.SLAVE)
.setTimeout(timeout);
//设置密码
if (StringUtils.isNotBlank(password)) {
serverConfig.setPassword(password);
}
}
return (Redisson) Redisson.create(config);
}
}