Redis学习篇-Springboot+redis哨兵模式(sentinel)

目录:

Redis学习篇-windows下redis主从模式搭建

Redis学习篇-windows下哨兵模式

 

前言:

通过结合前篇的redis sentinel与springboot达到增加理解的效果。本文采取1master2slave3sentinel.

 

一.预备工作

先启动master和两个slave,然后再启动sentinel.

redis端口依次为6379,6380,6381,sentinel依次是10001,10002,10003

二.创建springboot项目

pom文件

<properties>
   <java.version>1.8</java.version>
   <lombok.version>1.18.4</lombok.version>
</properties>

<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
      <exclusions>
         <exclusion>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
         </exclusion>
         <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
         </exclusion>
      </exclusions>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
   </dependency>

   <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>2.5.0</version>
      <!--<version>2.4.2</version>-->
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
   </dependency>
   <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
      <scope>provided</scope>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      <exclusions>
         <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
         </exclusion>
      </exclusions>
   </dependency>
</dependencies>

yml文件:

spring:
  redis:
    password: 123456
    jedis:
      pool:
        #最大连接数
        max-active: 1024
        #最大阻塞等待时间(负数表示没限制)
        max-wait: 20000
        #最大空闲
        max-idle: 200
        #最小空闲
        min-idle: 10
    sentinel:
      master: mymaster
      nodes: 127.0.0.1:10001,127.0.0.1:10002,127.0.0.1:10003
server:
  port: 9527

 

config文件:

@Configuration
@EnableAutoConfiguration
@Slf4j
public class RedisSentinelConfig {

    @Value("#{'${spring.redis.sentinel.nodes}'.split(',')}")
    private List<String> nodes;

    @Bean
    @ConfigurationProperties(prefix="spring.redis")
    public JedisPoolConfig getRedisConfig(){
        JedisPoolConfig config = new JedisPoolConfig();
        return config;
    }
    @Bean
    public RedisSentinelConfiguration sentinelConfiguration(){
        RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
        //配置matser的名称
        redisSentinelConfiguration.master("mymaster");
        //配置redis的哨兵sentinel
        Set<RedisNode> redisNodeSet = new HashSet<>();
        nodes.forEach(x->{
            redisNodeSet.add(new RedisNode(x.split(":")[0],Integer.parseInt(x.split(":")[1])));
        });
        log.info("redisNodeSet -->"+redisNodeSet);
        //哨兵模式添加set
        redisSentinelConfiguration.setSentinels(redisNodeSet);
        return redisSentinelConfiguration;
    }

    @Bean
    public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig, RedisSentinelConfiguration sentinelConfig) {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig,jedisPoolConfig);
        return jedisConnectionFactory;
    }
}

 

 启动服务:期间曾经遇到一个问题:

警告: Cannot get master address from sentinel running @ 127.0.0.1:6379. Reason: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused: connect. Trying next one.

问题的原因是因为sentinel绑定127.0.0.1的时候绑定自己本机ip或者指定ip地址

 完成这些以后日志:

经过sentinel找到redis地址。

接下来说说 JedisConnectionFactory

按照上面的配置,获得了JedisPoolConfig的bean和RedisSentinelConfiguration的bean.最终配置的JedisConnectionFactory。

点进JedisConnectionFactory类里面去,可以看到里面的类关系图,如图所示(网上找的)

å¨è¿éæå¥å¾çæè¿°

 时序图:

å¨è¿éæå¥å¾çæè¿°

 

 根据bean的生命周期,由于JedisConnectionFactory实现了InitializingBean因此先执行了afterPropertiesSet方法,在afterPropertiesSet方法里面调用createPool,一直调用,在initSentinels的方面里面调用了new JedisSentinelPool.MasterListener返回了masterlisenter,随后调用了masterlistener的start方法。

 

打断点进入initSentinels方法里面,先是根据yml的配置文件获取哨兵的ip和端口,然后根据sentinelGetMasterAndAddrByName获取redis主节点的ip和地址

  如下图所示,其实masterlistener是个内部类,继承了Thread.

在这个线程里面不停在遍历,获取redis的master节点。

 关闭主节点后,经过选举,和masterlinster的遍历循环,更改了主节点并告知了服务

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章