Jedis 资源实例耗尽,Web 应用程序块耗尽

Flo*_*Flo 4 deadlock connection-pooling blocking redis 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.GenericObjectPool.borrowObject(GenericObjectPool.java:1104)
redis.clients.util.Pool.getResource(Pool.java:20)
....
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的 JedisPoolConfig

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");
Run Code Online (Sandbox Code Playgroud)

显然,有些线程尝试获取 Jedis 实例,但池是空的,无法返回实例,因此池的默认行为是等待。

我已经仔细检查了整个代码,并且非常确定我将每个 Jedis 实例返回到我之前使用过的池中。所以我不确定为什么我的实例用完了。

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

除了不将 Jedis 实例返回到池中之外,还有其他方法可以创建内存漏洞吗?

vla*_*man 5

将资源返回到池中很重要,所以请记住这样做。否则,当关闭您的应用程序时,它将等待资源返回。

https://groups.google.com/forum/?fromgroups=#!topic/jedis_redis/UeOhezUd1tQ

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

Jedis jedis = JedisFactory.jedisPool.getResource();
try{
    jedis.set("key","val");
}finally{
    JedisFactory.jedisPool.returnResource(jedis);
}
Run Code Online (Sandbox Code Playgroud)