spring-boot-redis-starter源码分析

spring-boot-redis-starter源码分析

RedisAutoConfiguration自动配置类,redis链接工厂以及哨兵等监听

  1. RedisAutoConfiguration里面主要做JedisConnectionFactory的装配工作:
    根据配置的sentinel或者cluster进行不同的装配,加载配置等。
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public JedisConnectionFactory redisConnectionFactory()
    throws UnknownHostException {
   
   
  return applyProperties(createJedisConnectionFactory());
}
  1. JedisConnectionFactory实现了InitializingBean,在装载Bean之后调用afterPropertiesSet方法进行池JedisSentinelPool的创建
public void afterPropertiesSet() {
   
   
  if (shardInfo == null) {
   
   
    shardInfo = new JedisShardInfo(hostName, port);

    if (StringUtils.hasLength(password)) {
   
   
      shardInfo.setPassword(password);
    }

    if (timeout > 0) {
   
   
      setTimeoutOn(shardInfo, timeout);
    }
  }

  if (usePool && clusterConfig == null) {
   
   
    this.pool = createPool();
  }

  if (clusterConfig != null) {
   
   
    this.cluster = createCluster();
  }
}

这里主要是pool的创建,pool中主要存储的是Jedis对象,主要执行Jedis的管理工作,为后续连接的租借、归还进行一定的处理.

  1. JedisSentinelPool中首先initSentinels会根据sentinel的配置获取到主master节点的信息,遍历每个sentinel节点执行sentinel get-master-addr-by-name mymaster命令获取master(其中一个返回master即可)
for (String sentinel : sentinels) {
   
   
      final HostAndPort hap = HostAndPort.parseString(sentinel);

      log.fine("Connecting to Sentinel " + hap);

      Jedis jedis = null;
      try {
   
   
        jedis = new Jedis(hap.getHost(), hap.getPort());

        List<String> masterAddr = jedis.sentinelGetMasterAddrByName(masterName);

        // connected to sentinel...
        sentinelAvailable = true;

        if (masterAddr == null || masterAddr.size() != 2) {
   
   
          log.warning("Can not get master addr, master name: " + masterName + ". Sentinel: " + hap
              + ".");
          continue;
        }

        master = toHostAndPort(masterAddr);
        log.fine("Found Redis master at " + master);
        break;
      } catch (JedisException e) {
   
   
        log.warning("Cannot get master address from sentinel running @ " + hap + ". Reason: " + e
            + ". Trying next one.");
      } finally {
   
   
        if (jedis != null) {
   
   
          jedis.close();
        }
      }
    }
  1. 开启一个Daemon后台线程订阅+switch-master的消息,当master切换后收到sentinel发送的切换通知重新初始化连接pool。
for (String sentinel : sentinels) {
   
   
      final HostAndPort hap = HostAndPort.parseString(sentinel);
      MasterListener masterListener = new MasterListener(masterName, hap.getHost(), hap.getPort());
      // whether MasterListener threads are alive or not, process can be stopped
      masterListener.setDaemon(true);
      masterListeners.add(masterListener);
      masterListener.start();
    }
  1. MasterListener的作用就是对每个哨兵进行订阅消息,当收到通知后改变currentHostMaster,进行切换
MasterListener
@Override
    public void run() {
   
   
      running.set(true);
      while (running.get()) {
   
   
        j = new Jedis(host, port);
        try {
   
   
          // double check that it is not being shutdown
          if (!running.get()) {
   
   
            break;
          }
          j.subscribe(new JedisPubSub() {
   
   
            @Override
            public void onMessage(String channel, String message) {
   
   
              log.fine("Sentinel " + host + ":" + port + " published: " + message + ".");
              String[] switchMasterMsg = message.split(" ");
              if (switchMasterMsg.length > 3) {
   
   
                if (masterName.equals(switchMasterMsg[0])) {
   
   
                  initPool(toHostAndPort(Arrays.asList(switchMasterMsg[3], switchMasterMsg[4])));
                } else {
   
   
                  log.fine("Ignoring message on +switch-master for master name "
                      + switchMasterMsg[0] + ", our master name is " + masterName);
                }
              } else {
   
   
                log.severe("Invalid message received on Sentinel " + host + ":" + port
                    + " on channel +switch-master: " 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值