从JedisPool获取资源时,线程处于等待状态

时间:2017-06-27 12:41:45

标签: java multithreading redis jedis

我正在使用jedis连接redis服务器。 Redis ip值在单独的文件中配置,我正在尝试在初始化期间加载文件

private static JedisPool pool;

public static void initRedisClient() throws Exception {
   String redisConfigPath = "/conf/redis.properties";
   Properties docsRedisProp = RedisUtils.loadProperties(redisConfigPath);
   pool = new JedisPool(docsRedisProp.getProperty("redisserver"));    
   }
}

我从redis获取多个密钥的mget方法如下

public static List<String> mgetDataFromRedisCache(String[] keys) throws CacheException {
        Jedis jedisCon = null; 
        try {
            jedisCon = getJedis();
            jedisCon.select(1);
            return jedisCon.mget(keys);
        } catch (Exception e) {
            LOGGER.warning("Exception while fetching data from Redis Client. EXCEPTION=" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (jedisCon != null) {
                returnJedis(jedisCon);
            }
        }
        return null;
    }

当我在属性文件中给出错误的ip值时 - 访问它的请求线程正在等待很长一段时间。由于池中资源不可用,我的请求不应该停滞不前。

这里我附加了停滞线程的线程转储(即处于等待状态的线程)

###_http-nio-8443-exec-140" #104908 daemon prio=5 os_prio=0 tid=0x00007f247805f000 nid=0x4266 waiting on condition [0x00007f220a4df000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000006fe438408> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at org.apache.commons.pool2.impl.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:524)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:438)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
    at redis.clients.util.Pool.getResource(Pool.java:40)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:84)
    at com.retail.store.RedisClient.getJedis(RedisClient.java:53)
    at com.retail.store.RedisClient.mgetDataFromRedisCache(RedisClient.java:82)

我怎么能实现这个目标?任何帮助深表感谢。在此先感谢: - )

2 个答案:

答案 0 :(得分:2)

redis服务器ip维护在属性文件中并在运行时加载它。

属性文件包含默认ip。但是当我在我的开发设置中部署相同的时候,redis ip应该已经改变但是我错过了这样做。我的开发设置无法与给定的ip连接。

Jedis具有以下默认配置

  

最大活动连接数= 8

     

readtimeout = 2000

Maximum active connections是池可以同时保存的最大活动连接数。

read time out是建立连接并准备通过已建立的连接接收数据时设置的最长时间(毫秒)。

在我们的情况下,未建立连接(对于前8个线程)并且它永远不会被终止 - 连接是超时没有为这些连接设置。使get调用redis的其他线程现在进入停放WAIT状态。

通过设置以下池配置(即;设置建立连接的最长等待时间),我们可以避免线程进入延长等待状态

JedisPoolConfig jedisConfig = new JedisPoolConfig();
jedisConfig.setMaxWaitMillis(maxWaitInMillis);

答案 1 :(得分:0)

您可以使用相应的constructor创建短暂超时的jedis连接。

Jedis jedisCon = public Jedis(String host, int port, int timeout);