第二十八节 SpringBoot连接哨兵模式的Redis集群

亮子 2023-01-30 09:38:46 1364 0 0 0

springboot项目更多的采用RedisTemplate类连接redis,而不是采用Jedis。

1、引入相关依赖

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

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-pool2</artifactId>
</dependency>

2、springboot项目核心配置

server:
  port: 8080

spring:
  redis:
    database: 0
    timeout: 3000
    sentinel:    #哨兵模式
      master: mymaster #主服务器所在集群名称
      nodes: 192.168.43.10:26379,192.168.43.10:26380,192.168.43.10:26381
   lettuce:
      pool:
        max-idle: 50
        min-idle: 10
        max-active: 100
        max-wait: 1000

3、访问代码

@RestController
public class IndexController {

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 测试节点挂了哨兵重新选举新的master节点,客户端是否能动态感知到
     * 新的master选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制,
     * 当哨兵把新master的消息发布出去,客户端会立马感知到新master的信息,从而动态切换访问的masterip
     *
     * @throws InterruptedException
     */
    @RequestMapping("/test_sentinel")
    public void testSentinel() throws InterruptedException {
        int i = 1;
        while (true){
            try {
                stringRedisTemplate.opsForValue().set("zhuge"+i, i+"");
                System.out.println("设置key:"+ "zhuge" + i);
                i++;
                Thread.sleep(1000);
            }catch (Exception e){
                logger.error("错误:", e);
            }
        }
    }
}

4、普通代码访问

该代码模拟的是:Java代码的redis客户端不会直接与redis主机连接,而是通过哨兵连接redis的主机。

public class JedisSentinelTest {
    public static void main(String[] args) throws IOException {

        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxIdle(10);
        config.setMinIdle(5);

        String masterName = "mymaster";
        Set<String> sentinels = new HashSet<String>();
        sentinels.add(new HostAndPort("192.168.43.10",26379).toString());
        sentinels.add(new HostAndPort("192.168.43.10",26380).toString());
        sentinels.add(new HostAndPort("192.168.43.10",26381).toString());
        //JedisSentinelPool其实本质跟JedisPool类似,都是与redis主节点建立的连接池
        //JedisSentinelPool并不是说与sentinel建立的连接池,而是通过sentinel发现redis主节点并与其建立连接
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, config, 3000, null);
        Jedis jedis = null;
        try {
            jedis = jedisSentinelPool.getResource();
            System.out.println(jedis.set("sentinel", "zhuge"));
            System.out.println(jedis.get("sentinel"));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
            if (jedis != null)
                jedis.close();
        }
    }
}

参考文章