做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 }