redis集群JedisCluster连接关闭问题

时间:2020-01-08 16:45:55   收藏:0   阅读:341

JedisCluster连接关闭问题

set方法为例

//伪代码
JedisCluster jedisCluster = new JedisCluster();
jedisCluster.set("testKey", "testValue");

进入到set方法

public String set(final String key, final String value) {
   return new JedisClusterCommand<String>(connectionHandler, maxAttempts) {
     @Override
     public String execute(Jedis connection) {
       return connection.set(key, value);
     }
   }.run(key);
 }

进入到run方法

public T run(String key) {
   return runWithRetries(JedisClusterCRC16.getSlot(key), this.maxAttempts, false, null);
 }

进入到runWithRetries方法

private T runWithRetries(final int slot, int attempts, boolean tryRandomNode, JedisRedirectionException redirect) {
    if (attempts <= 0) {
      throw new JedisClusterMaxAttemptsException("No more cluster attempts left.");
    }

    Jedis connection = null;
    try {
        //此处为空,走else
      if (redirect != null) {
        connection = this.connectionHandler.getConnectionFromNode(redirect.getTargetNode());
        if (redirect instanceof JedisAskDataException) {
          // TODO: Pipeline asking with the original command to make it faster....
          connection.asking();
        }
      } else {
        //此处是false,走else
        if (tryRandomNode) {
          connection = connectionHandler.getConnection();
        } else {
          //这里会从池中获取一个Jedis对象
          connection = connectionHandler.getConnectionFromSlot(slot);
        }
      }
        //这里调用最开始实现的execute方法
      return execute(connection);

    } catch (JedisNoReachableClusterNodeException jnrcne) {
      throw jnrcne;
    } catch (JedisConnectionException jce) {
      // release current connection before recursion
      releaseConnection(connection);
      connection = null;

      if (attempts <= 1) {
        //We need this because if node is not reachable anymore - we need to finally initiate slots
        //renewing, or we can stuck with cluster state without one node in opposite case.
        //But now if maxAttempts = [1 or 2] we will do it too often.
        //TODO make tracking of successful/unsuccessful operations for node - do renewing only
        //if there were no successful responses from this node last few seconds
        this.connectionHandler.renewSlotCache();
      }

      return runWithRetries(slot, attempts - 1, tryRandomNode, redirect);
    } catch (JedisRedirectionException jre) {
      // if MOVED redirection occurred,
      if (jre instanceof JedisMovedDataException) {
        // it rebuilds cluster's slot cache recommended by Redis cluster specification
        this.connectionHandler.renewSlotCache(connection);
      }

      // release current connection before recursion
      releaseConnection(connection);
      connection = null;

      return runWithRetries(slot, attempts - 1, false, jre);
    } finally {
      //此处释放了连接
      releaseConnection(connection);
    }
  }

进入到releaseConnection方法

private void releaseConnection(Jedis connection) {
    if (connection != null) {
      connection.close();
    }
  }

总结

原文:https://www.cnblogs.com/xiaodf/p/12167268.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!