Java Jedis:无法从池中获取资源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23233673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jedis : Could not get a resource from the pool
提问by WoooHaaaa
Background
背景
Our application uses Jedis-2.2.1
and connects to Redis-2.6
, here's how I get jedis resource :
我们的应用程序使用Jedis-2.2.1
并连接到Redis-2.6
,这是我获取 jedis 资源的方式:
protected static JedisWrapper getRedisUserWrite(String UDID) {
if (redisUserWritePools.get(0) == null) init();
int hash = hash(UDID);
Jedis jedis = redisUserWritePools.get(hash).getResource();
jedis.select(dbs.get("redisUserWritePools" + hash));
return new JedisWrapper(jedis, redisUserWritePools.get(hash));
}
And this is my JedisWrapper
(Unify the management of resources):
这是我的JedisWrapper
(统一资源管理):
public class JedisWrapper {
private Jedis jedis;
private JedisPool pool;
public JedisWrapper(Jedis jedis, JedisPool pool) {
this.jedis = jedis;
this.pool = pool;
}
public Jedis get(){
return this.jedis;
}
public void returnResource() {
if(null != this.jedis){
this.pool.returnResource(this.jedis);
}
}
public void returnBrokenResource() {
if(null != this.jedis) {
this.pool.returnBrokenResource(this.jedis);
}
this.jedis = null;
}
}
JedisWrapper
is the container if Jedis instance, here's how I use it :
JedisWrapper
是容器如果 Jedis 实例,这是我如何使用它:
private static void cacheSDKIDs(String UDID, String[] SDKIDs) {
JedisWrapper wrapper = getRedisUserWrite(UDID);
try {
if (SDKIDs != null) {
wrapper.get().del(UDID);
wrapper.get().sadd(UDID, SDKIDs);
}
} catch (JedisConnectionException e) {
e.printStackTrace();
wrapper.returnBrokenResource();
}catch (Exception e) {
e.printStackTrace();
} finally {
wrapper.returnResource();
}
}
Note that, SKDIDs
maybe very large(e.g. could reach the maximum of 8KB).
请注意,SKDIDs
可能非常大(例如可能达到 8KB 的最大值)。
Here's the problem
问题来了
Every time I restart our application, all redis connections are normal, but several hours
later, the Could not get a resource from the pool
Exception comes out. And frequency become higher and higher, then all the connections to Redis are disconnected and can create new connection.
每次重启我们的应用程序,所有redis连接都正常,但是几个小时后,Could not get a resource from the pool
异常就出来了。并且频率越来越高,然后所有到Redis的连接都断开了,可以创建新的连接。
Here's my configuration :
这是我的配置:
<bean id = "redisConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="400" />
<property name="maxIdle" value="100" />
<property name="minIdle" value="20" />
<property name="maxWait" value="4000" />
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true" />
</bean>
Exception Stacktrace:
异常堆栈跟踪:
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:40)
at com.xxxice.redis.BaseRedis.getRedisUserWrite(BaseRedis.java:158)
at com.xxx.service.redis.DeviceRedis.cacheSDKIds(DeviceRedis.java:128)
at com.xxx.redis.DeviceRedis.cacheDevice(DeviceRedis.java:65)
at com.xxx.service.DeviceService.update(DeviceService.java:88)
at com.xxx.controller.Devices.update(Devices.java:25)
... 32 more
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1174)
at redis.clients.util.Pool.getResource(Pool.java:38)
... 37 more
回答by Remya
In your JedisWrapper, the Jedis is created as a class variable which gets instantiated once. Please declare it inside the methods getJedis, then the problem will be solved
在您的 JedisWrapper 中,Jedis 被创建为一个实例化一次的类变量。请在getJedis方法里面声明一下,问题就解决了
回答by samith kumarasingha
check whether you have permission to access redis through code
检查是否有权限通过代码访问redis