JedisPool报错:Could not return the resource to the pool
Bug的起源和解法
这个错误来的实在猝不及防,第一次请求可以成功使用JedisPool
,而第二次请求便会报错,在翻遍了所有相关博客后一度以为是自己的配置出了错,于是不断修改配置文件中的redis连接池参数。
折腾老半天之后,没有帮助TAT
这时,我想起10年前的某个午后,蝉鸣的空气中传来的几分安定,出神地趴在窗边看麻雀扑腾的我,被一声厉呵带回现实。之后便到了标准环节–”下课到办公室找我”。之后的事情便记不太清了,只是我深深地记得当时的心境,想不出的问题换个角度想,一定会有不同的发现。
那就回归报错吧,“无法将资源返回到池”,再回想到我的jedisPool对象,旷的一声,仿佛天旋地转一般,一切的一切突然都变透彻了。
错误根源及出错原因
1 |
|
JedisPool在configuration类中初始化(项目启动时有spring自动扫描)
然而在每个业务类调用完之后就被手动关闭,自然执行完第一次后就不再能取出resource的,也无法return。
解决这个bug只需把每个service实现类中的jedisPool.close()
删去即可。
为什么会出现这种写法
说到这个就不得不提起Jedis的wiki
官方po出的demo是这样使用jedis的:
首先引入pom
1 | <dependency> |
然后实例化JedisPool
1 | JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost"); |
接着实例化jedis有两种方法
- try-with-resource法
1
2
3
4
5
6
7
8
9
10/// Jedis implements Closeable. Hence, the jedis instance will be auto-closed after the last statement.
try (Jedis jedis = pool.getResource()) {
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike");
Set<String> sose = jedis.zrange("sose", 0, -1);
}
/// ... when closing your application:
pool.close();// 这便是原罪 - 手动关闭jedis法虽然不在报错了,但是现在不关的话又不知道在哪能关的了它了。。。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18Jedis jedis = null;
try {
jedis = pool.getResource();
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike");
Set<String> sose = jedis.zrange("sose", 0, -1);
} finally {
// You have to close jedis object. If you don't close then
// it doesn't release back to pool and you can't get a new
// resource from pool.
if (jedis != null) {
jedis.close();
}
}
/// ... when closing your application:
pool.close();
双手奉上: Jedis官方指引