redis.clients.jedis.exceptions.JedisExhaustedPoolException: Could not get a resource since the pool is exhausted
做JedisPool时遇到的问题还真不少,遇到了入下问题,这里提供一个解决办法,不一定使用所有人遇到的情况,因为可能有很多人使用的是在虚拟机里配置的redis,我用的配置是centos服务器上的redis,问题的原因可能就是出自这里,因为如果是本地的话,redis.conf里面的配置默认是 bind 127.0.0.1,而远程连接的话要将这句配置注释掉,并且非本地连接时会默认进入保护模式?需要设置密码或者修改其他的配置以达到访问的目的。
比如以下的提示
Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.
本次要解决的错误:
redis.clients.jedis.exceptions.JedisExhaustedPoolException: Could not get a resource since the pool is exhausted
at redis.clients.jedis.util.Pool.getResource(Pool.java:53)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:234)
at com.jedis.jedistest.PoolTest.main(PoolTest.java:15)
Caused by: java.util.NoSuchElementException: Unable to validate object
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:479)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:346)
at redis.clients.jedis.util.Pool.getResource(Pool.java:50)
... 2 more
百度Google找到的解决办法都不适用,后来想到,可能是由于远程访问时没设置密码导致的?刚好看到这里的讨论,https://www.oschina.net/question/579073_113004
于是就将poolConfig.setTestOnBorrow(false); 从原来的true改为false,并给redis设置了密码123,访问可以进行。
以下给出原视频链接:https://www.bilibili.com/video/av51989396/?p=28
代码是照着里面敲的,不过有些包的版本不同,所以有些方法改变了。
JedisPoolUtil.java
package com.jedis.jedistest; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; //Double Chcek Lock public class JedisPoolUtil { private static volatile JedisPool jedisPool = null; // 构造方法私有化 private JedisPoolUtil() { } // 通过一个方法返回池的实例 public static JedisPool getJedisPoolInstance() { if (null == jedisPool) { // 锁定对象 synchronized (JedisPoolUtil.class) { if (null == jedisPool) { JedisPoolConfig poolConfig = new JedisPoolConfig(); // poolConfig.setMaxTotal(1000); poolConfig.setMaxTotal(1000); poolConfig.setMaxIdle(32); poolConfig.setMaxWaitMillis(100 * 1000); poolConfig.setTestOnBorrow(false); // poolConfig.setTestOnBorrow(true); jedisPool = new JedisPool(poolConfig, "233.233.223.223", 6666); } } } return jedisPool; } public static void release(JedisPool jedispool,Jedis jedis) { if(null!=jedis) { //jedisPool.returnResource(jedis) ---> jedis.close(); //升级版的jedis用close来替代returnResource? //jedispool.getResource(); jedis.close(); } } }
PoolTest.java
1 package com.jedis.jedistest; 2 3 import redis.clients.jedis.Jedis; 4 import redis.clients.jedis.JedisPool; 5 6 public class PoolTest { 7 8 public static void main(String[] args) { 9 10 JedisPool jedisPool = JedisPoolUtil.getJedisPoolInstance(); 11 Jedis jedis = null; 12 13 14 try { 15 jedis = jedisPool.getResource(); 16 jedis.auth("123"); 17 jedis.set("k1", "siyi"); 18 } catch (Exception e) { 19 e.printStackTrace(); 20 }finally { 21 JedisPoolUtil.release(jedisPool, jedis); 22 } 23 24 } 25 26 }