Redis Jedis的资源实例、web应用程序块正在用尽

Redis Jedis的资源实例、web应用程序块正在用尽,redis,connection-pooling,deadlock,blocking,jedis,Redis,Connection Pooling,Deadlock,Blocking,Jedis,我正在运行一个Tomcat应用程序,它使用Jedis访问Redis数据库。不时形成整个应用程序块。通过使用JavaMelody监视Tomcat,我发现问题似乎与对象请求Jedis实例时的JedisPool有关 catalina-exec-74 java.lang.Object.wait(Native Method) java.lang.Object.wait(Object.java:503) org.apache.commons.pool.impl.GenericObjectP

我正在运行一个Tomcat应用程序,它使用Jedis访问Redis数据库。不时形成整个应用程序块。通过使用JavaMelody监视Tomcat,我发现问题似乎与对象请求Jedis实例时的JedisPool有关

catalina-exec-74
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:503)
org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104)
redis.clients.util.Pool.getResource(Pool.java:20)
....
这是我正在使用的配置

JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxActive(20);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setMaxIdle(5);
poolConfig.setMinIdle(5);
poolConfig.setTestWhileIdle(true);
poolConfig.setNumTestsPerEvictionRun(10);
poolConfig.setTimeBetweenEvictionRunsMillis(10000);
jedisPool = new JedisPool(poolConfig, "localhost");
因此,显然有些线程试图获取一个Jedis实例,但池是空的,无法返回实例,因此默认池行为是wait

我已经仔细检查了我的全部代码,我非常确定我会将所有绝地武士的实例都返回到我以前使用过的池中。所以我不知道为什么我的实例已经用完了

有没有办法检查池中还有多少实例?我试图为maxActive参数找到一个合理的值,以防止应用程序阻塞

除了不将绝地实例返回池中之外,还有其他方法来创建内存洞吗

将资源返回到池中很重要,因此请记住这样做。否则,在关闭应用程序时,它将等待资源返回

每次调用Jedis方法后,返回资源池。你的应用程序可能已经使用了所有线程,并等待删除一些线程。这可能会导致您正在解释的行为,并且应用程序可能已被阻止

Jedis Jedis=JedisFactory.jedisPool.getResource();
试一试{
绝地武士组(“钥匙”、“瓦尔”);
}最后{
绝地工厂。绝地卷轴。返回资源(绝地);
}

希望对类似情况下的人们有所帮助,尽管我不确定我的问题是否与你的问题相同(如果你已经解决了,请告诉我们!)

我已经仔细检查了我的全部代码,我非常确定我会将所有绝地武士的实例都返回到我以前使用过的池中。所以我不知道为什么我的实例已经用完了

我认为我必须-我总是将代码放在try/finally块中,但事实证明我确实存在内存泄漏:

Jedis jedis = DBHelper.pool.getResource();
    try {
        // Next line causes the leak
        Jedis jedis = DBHelper.pool.getResource();
        ...
    } finally {
        DBHelper.pool.returnResource(jedis);
    }
不知道第二次呼叫是如何潜入的,但它确实潜入了,并导致了泄漏和web应用程序的阻塞

有没有办法检查池中还有多少实例?我试图为maxActive参数找到一个合理的值,以防止应用程序阻塞

在我的例子中,我发现了错误,并根据redis服务器看到的客户端数量进行了优化。我将日志级别(在
redis.conf
中设置为
verbose
(默认值为
notice
),它将每隔5-10秒报告连接的客户端数量。一旦发现内存泄漏,我会反复向调用该方法的页面发送请求,看到redis日志报告的redis客户端不断上升,但从未下降。。我认为这将是优化的一个良好开端


无论如何,希望这对某人有帮助!

你解决了这个问题吗?我遇到了完全相同的问题,正如你所说的,我非常确定所有连接都会返回(我使用的是DAO模式,所以只有一个类使用绝地)。提前感谢。