在项目中使用redis做缓存,当运行一段时间后就会出现如下错误:Could not get a resource from the pool,然后在看具体的异常信息就是JedisPool中获取不到jedis对象,也就是说连接池中没有可用的jedis。
自己的第一反应就是把最大链接数(setMaxTotal)调大一些,刚开始设置了100、后来200、在后来2000都不行
然后上网一搜发现大家的回答也都是修改最大连接数,如下demo就是网上一篇博客的解释:
1、产生原因:客户端去redis服务器拿连接(代码描述的是租用对象borrowObject)的时候,池中无可用连接,即池中所有连接被占用,且在等待时候设定的超时时间后还没拿到时,报出此异常。
2、解决办法:调整JedisPoolConfig中maxActive为适合自己系统的阀值。
[color=red] [/color]
但这个自己也设置了,配置如下:
#最大活动对象数
redis.pool.maxTotal=1000
#最大能够保持idel状态的对象数
redis.pool.maxIdle=100
#最小能够保持idel状态的对象数
redis.pool.minIdle=50
#当池内没有返回对象时,最大等待时间
redis.pool.maxWaitMillis=10000
#当调用borrow Object方法时,是否进行有效性检查
redis.pool.testOnBorrow=true
#当调用return Object方法时,是否进行有效性检查
redis.pool.testOnReturn=true
#“空闲链接”检测线程,检测的周期,毫秒数。如果为负值,表示不运行“检测线程”。默认为-1.
redis.pool.timeBetweenEvictionRunsMillis=30000
#向调用者输出“链接”对象时,是否检测它的空闲超时;
redis.pool.testWhileIdle=true
# 对于“空闲链接”检测线程而言,每次检测的链接资源的个数。默认为3.
redis.pool.numTestsPerEvictionRun=50
#表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
MinEvictableIdleTimeMillis=60000
#redis服务器的IP
redis.ip=xxxxxx
#redis服务器的Port
redis1.port=6379
但是这样设置后,当运行一段时候后还是会报同样的错误,说句不爱听的话最大链接数“1000”这个值真的不小,但还是错误,所以肯定不是这个值的原因。
后来在网上找到了一篇文章,文章中的jedis工具类中有三个方法,代码如下:
public class JedisUtils {
private static Log logger = LogFactory.getLog(JedisUtils.class);
/**
* 自动注入Redis连接实例对象线程池
*/
@Autowired
private JedisPool jedisPool;
/**
* 获取Jedis对象
*
* @return
*/
public synchronized Jedis getJedis() {
Jedis jedis = null;
if (jedisPool != null) {
try {
if (jedis == null) {
jedis = jedisPool.getResource();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
return jedis;
}
/**
* 回收Jedis对象资源
*
* @param jedis
*/
public synchronized void returnResource(Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}
/**
* Jedis对象出异常的时候,回收Jedis对象资源
*
* @param jedis
*/
public synchronized void returnBrokenResource(Jedis jedis) {
if (jedis != null) {
jedisPool.returnBrokenResource(jedis);
}
}
}
业务类、方法代码如下:
Jedis jedis = jedisUtils.getJedis();
if(jedis == null){
throw new NullPointerException("Jedis is Null");
}
try{
long queueCurrValue = jedis.llen(messageQueueName);
if(queueCurrValue >= queueMaxSize){
return addFlag;
}
String serizlizetValue = JSON.toJSONString(message);
if(StringUtils.isNotBlank(serizlizetValue)){
long queueLength = jedis.lpush(messageQueueName, serizlizetValue);
if(queueLength - queueCurrValue > 0){
addFlag = true;
}
}
}catch(Exception e){
jedisUtils.returnBrokenResource(jedis);
logger.error(e.getMessage(), e);
}finally{
jedisUtils.returnResource(jedis);
}
#最大链接数
MaxTotal=100
#空闲时最大链接数
MaxIdle=20
#空闲最小
MinIdle=8
#链接最大等待时间 (毫秒)
MaxWaitMillis=10000
单我在项目中使用的时候有如下问题:
// 释放资源
public synchronized void returnResource(Jedis jedis) {
if (jedis != null) {
pool.returnResource(jedis);
}
}
// 出现异常释放资源
public synchronized void returnBrokenResource(Jedis jedis) {
if (jedis != null) {
pool.returnBrokenResource(jedis);
}
}
相关文章推荐:
http://www.codeweblog.com/redis%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA-%E9%85%8D%E7%BD%AE-%E5%8F%8Ajedis%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/
http://www.codeweblog.com/jedis%E8%BF%9E%E6%8E%A5%E6%B1%A0%E9%85%8D%E7%BD%AE/
http://www.codeweblog.com/jedis-returnresource%E4%BD%BF%E7%94%A8%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/
http://fengguang0051.iteye.com/blog/2237171