SpringBoot配置Redis哨兵模式
所谓哨兵模式,其实是一个伪集群,即便是在多个哨兵的情况下,哨兵监控的都是同一个主节点,也就是一主多从的模式。
SpringBoot配置哨兵模式,只需要配置哨兵的IP和端口,不需要配置主从节点的信息,当主节点挂掉后,哨兵会自动完成主从切换,直接上代码
@Configuration
public class JedisPoolConfiguration {
/**
* jedis连接池配置
* @return
* @Bean 加载后,方法返回的对象作为bean,被放在IOC容器里
*/
@Bean
/*@ConfigurationProperties(prefix = "jedisPool")*/
public JedisPoolConfig jedisPoolConfig(){
System.out.println("配置类执行了");
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
return jedisPoolConfig;
}
@Bean
public RedisSentinelConfiguration sentinelConfiguration(){
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration();
Set<RedisNode> redisNodes = new HashSet<>();
//ip和端口信息可以写在配置文件里
RedisNode redisNode = new RedisNode("192.168.1.128",26379);
RedisNode redisNode2 = new RedisNode("192.168.1.128",26380);
RedisNode redisNode3 = new RedisNode("192.168.1.128",26381);
redisNodes.add(redisNode);
redisNodes.add(redisNode2);
redisNodes.add(redisNode3);
//setSentinels的参数类型是Iterable<RedisNode>,所以放有RedisNode的集合可以是实现Iterable接口的任意集合,使用list、set都可以
sentinelConfiguration.setSentinels(redisNodes);
//监控主节点的名称
sentinelConfiguration.setMaster("mymaster");
return sentinelConfiguration;
}
/**
* 连接工厂配置信息,需要注入连接池配置信息
* @param jedisPoolConfig
* @return
*/
@Bean
public JedisConnectionFactory jedisConnectionFactory(RedisSentinelConfiguration redisSentinelConfiguration,JedisPoolConfig jedisPoolConfig){
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisSentinelConfiguration,jedisPoolConfig);
return jedisConnectionFactory;
}
/**
* 操作redis方法的对象,需要注入连接工厂,封装了操作redis的方法
* @param jedisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String,Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
//使用的时候再具体转换序列化方式,存取都需要
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
return redisTemplate;
}
}
在其他业务代码中,注入redisTemplate,使用就可以了
配置的过程中遇到几个问题,希望大家引以为戒:
1.
连接不到哨兵,All sentinels down
查了很多资料,有说是防火墙的问题,我把Linux服务器、window的服务器防火墙都关了,在windows上使用telnet也是通的,把 sentinel.conf文件中的bind也设置为了0.0.0.0,保护模式也关闭了protected-mode no,还是不行,最后检查了下代码,原来是装有哨兵节点信息的集合没有放到sentinelConfiguration中,也就是没写sentinelConfiguration.setSentinels(redisNodes);这段代码,真是气自己呀,重启后,项目正常运行,redis也可以正常使用。
2.手动关闭主节点后,通过info replication查看其它节点信息,其中一个从节点成功切换为主节点,说明哨兵配置的是没有问题的,但是项目报错如下:
Could not get a resource from the pool
没有拿到redis连接,也就是redis不可用,很奇怪,从节点都成功切换为主节点了,哨兵怎么还是找不到主节点,查看了下哨兵的配置文件,发现监控的主节点IP地址变成了127.0.0.1,之前配置的是服务器的ip 192.168.1.128,重启哨兵,项目正常运行了,不知道这种问题是不是由于虚拟机的问题造成的
3.建议每次重启哨兵的时候,将 sentinel.conf配置文件中
Generated by CONFIG REWRITE
被重写的这部分内容删除再重启。