jedisPool.getResource()方法长时间无响应并且不报错

一个Java Web的系统需要动态根据Redis地址获取数据,截取相关代码如下:

获取连接的方法:

public static JedisCluster getConn(String host, int port)
  {
    String key = getKey(host, port);
    JedisCluster jedisCluster = (JedisCluster)jedisConnMap.get(key);
    if (jedisCluster == null) {
      try {
        LOG.debug("jedisCluster is empty.");
        HostAndPort hostAndPort = new HostAndPort(host, port);
        Set hpset = Sets.newHashSet(new HostAndPort[] { hostAndPort });
        jedisCluster = new JedisCluster(hpset, 30);
      } catch (JedisException e) {
        LOG.error("create jediscluster error: {}", e);
      }
      if (jedisCluster != null) {
        jedisConnMap.put(key, jedisCluster);
      }
    }
    return jedisCluster;
  }

调用的代码块:

JedisCluster jedisCluster = JedisConnCacheUtil.getConn(host, port);
if (jedisCluster == null) {
   LOG.debug("get jedisCluster error.");
   return;
}
Map jedisPools = jedisCluster.getClusterNodes();
for (String jedisAdr : jedisPools.keySet()){
    JedisPool jedisPool = (JedisPool)jedisPools.get(jedisAdr);
    Jedis jedis = jedisPool.getResource();
    //后面是对Jedis的具体操作
}

由于调用的代码是跑在一个定时任务里,出现的异常情况是,前几次数据都可以正常获取,大约几分钟后,定时任务就没有运行了,也没有任何报错。
通过捕获JVM ThreadDump,发现有一个线程在Jedis jedis = jedisPool.getResource()这行一直waiting。
也就是这行代码长时间无响应阻塞了整个定时任务。很奇怪,如果无法获取Resource应该也要报错,可是什么也没有。
查询了官方文档,原来new JedisCluster(hpset, 30)中默认了MaxWaitMillis为-1。

BlockWhenExhausted:连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true

MaxWaitMillis:获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常,小于零:阻塞不确定的时间, 默认-1

由于BlockWhenExhausted默认为true,连接耗尽时会阻塞到超时,但是MaxWaitMillis默认为-1,超时时间是一个不确定的时间,所以就一直阻塞着了。
修改配置后问题解决。

你可能感兴趣的:(java,redis,jedis,超时,无响应)