JedisPool的JedisConnectionException: 的解决办法

项目使用JedisPool做的jedis连接池,运行了一段时间之后报出如下错误

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
 at redis.clients.util.Pool.getResource(Pool.java:22)
 at com.jh.repo.redis.BossRedisRepoImpl.addBossManager(BossRedisRepoImpl.java:50)
 at com.jh.exGateService.controller.server.db.controller.BossBattleStart.clientTodo(BossBattleStart.java:36)
 at com.jh.serviceFrame.controller.Controller.syncClientTodo(Controller.java:50)
 at com.jh.serviceFrame.controller.ChannelManager$ClientMessageSetupServer.todo(ChannelManager.java:216)
 at com.jh.serviceFrame.task.SetupTask.processTask(SetupTask.java:38)
 at com.jh.serviceFrame.task.Task.run(Task.java:42)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
 at java.lang.Thread.run(Thread.java:744)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
 at redis.clients.jedis.Protocol.process(Protocol.java:75)
 at redis.clients.jedis.Protocol.read(Protocol.java:123)
 at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:137)
 at redis.clients.jedis.Jedis.auth(Jedis.java:2015)
 at redis.clients.jedis.JedisPool$JedisFactory.makeObject(JedisPool.java:65)
 at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1158)
 at redis.clients.util.Pool.getResource(Pool.java:20)

 

代码如下

 public void initJedisPool(JedisConfig config){
  if(config==null){
   logger.warn("redis 配置文件没有读取出来");
   return;
  }
  JedisPoolConfig poolConfig = new JedisPoolConfig();
  poolConfig.setMaxActive(config.getMaxActive());
  poolConfig.setMaxIdle(config.getMaxIdle());
  poolConfig.setMaxWait(config.getMaxWait());
  poolConfig.setTestOnBorrow(config.isTestOnBorrow());
  poolConfig.setTestOnReturn(config.isTestOnReturn());
  pool = new JedisPool(poolConfig, config.getRedisIp(), config.getRedisPort(), timeout, Common.REDIS_PASSWORD);
 }

配置代码如下:
redis.pool.maxActive=128
redis.pool.maxIdle=64
redis.pool.maxWait=1000
redis.pool.testOnBorrow=false
redis.pool.testOnReturn=false
redis.ip=127.0.0.1
redis.port=6379

 

原因是因为无法从jedis连接池中获得Jedis对象。分析了下,我的程序中没有同时使用128个连接的情况,另外即便有,也应该在1000毫秒内总会有个连接对象归还回池中,在网上找了些资料,说要将redis.pool.maxActive=128配置为一个适当的阀值,我依照帖子的意思改redis.pool.maxActive=128为1024,过了段时间还是出现这样的异常,不论如何,将redis.pool.maxActive改无限大也不是一个现实的办法,我寻思maxActive的数目根本不是抛出这个异常的关键所在,继续在网上找资料,国外有个人说

pool = new JedisPool(poolConfig, config.getRedisIp(), config.getRedisPort(), timeout, Common.REDIS_PASSWORD);这句代码中的
timeout的意思是当在timeout时间之外,那么就会自动将出于Idle状态的jedis对象销毁掉;这个说法迁移到我的代码中大体意思如下:

假定timeout=60 单位是秒

当jedisPool中有64个处于IDLE的jedis,那么在60秒后将会从连接池中销毁掉这64个jedis对象,这样几次执行下来,但凡有空闲的jedis都会在一定情况下被销毁掉;

所以解决方案是:要么不要让jedis对象闲下来,要么让销毁动作不要执行,我选择了后者,抱着试一试的态度,将timeout的值设置为0(在一些产品中,将超时时间设置为0,表示永不超时,比如netty的一些参数的值的设定),结果成了,问题解决掉了,也许并没有真正的解决掉,但是在测试几次下来还没有在出现这样子的情况

最后:希望大神们来指正,小弟先谢谢各位了

你可能感兴趣的:(get,resource,from,pool,could,a,the,not)