在redis-cli 中敲命令:client list 可以查看已连接的请求 异常描述: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:22)
at com.derbysoft.jredis.longkeytest.BorrowObject.run(BorrowObject.java:22)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1134)
at redis.clients.util.Pool.getResource(Pool.java:20)
... 2 more
1、产生原因:客户端去redis服务器拿连接(代码描述的是租用对象borrowObject)的时候,池中无可用连接,即池中所有连接被占用,且在等待时候设定的超时时间后还没拿到时,报出此异常。 2、解决办法:调整JedisPoolConfig中maxActive为适合自己系统的阀值。 <bean id="dataJedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> [color=red]<property name="maxActive" value="5000"/>[/color] <property name="maxIdle" value="5000"/> <property name="maxWait" value="10000"/> <property name="testOnBorrow" value="true"/> </bean> 3、重现: public class BorrowObject implements Runnable { private ShardedJedisPool jedisPool; public BorrowObject(ShardedJedisPool jedisPool) { this.jedisPool = jedisPool; } @Override public void run() { ShardedJedis shardedJedis = null; try { shardedJedis = jedisPool.getResource(); String value = shardedJedis.hget("LONG_KEY_TEST:AA059E03E0AB7D806E6C351F87404B06C1190", "Roc El Pinar Aparthotel"); System.out.println(value); } catch (Exception e) { //logger.error(e); e.printStackTrace(); } finally { jedisPool.returnResource(shardedJedis); } } } public class BorrowObjectTest { private ShardedJedisPool jedisPool = null; public BorrowObjectTest() { List<JedisShardInfo> jedisShardInfos = new ArrayList<JedisShardInfo>(); JedisShardInfo jedisShardInfo = new JedisShardInfo("192.168.1.112"); jedisShardInfo.setTimeout(1000000); jedisShardInfos.add(jedisShardInfo); jedisPool = new ShardedJedisPool(createJedisConfig(), jedisShardInfos); } private JedisPoolConfig createJedisConfig() { JedisPoolConfig jedisConfig = new JedisPoolConfig(); [color=red]jedisConfig.setMaxActive(2);[/color] jedisConfig.setMaxIdle(2); jedisConfig.setMaxWait(5); jedisConfig.setTestOnBorrow(true); return jedisConfig; } public static void main(String[] args) { BorrowObjectTest borrowObjectTest = new BorrowObjectTest(); for (int i = 0; i < 300; i++) { new Thread(new BorrowObject(borrowObjectTest.jedisPool)).start(); } } }
1 楼
dilaomi123
2012-05-07
你好~~~看了您的文章收益匪浅,我也遇到类似的问题,但是我设置了阀值以后,同时跑5000个线程去取数据,还是报同样的错误,非常郁闷.还请不吝啬赐教,不胜感激 package com.sz7road.web.action.online.user; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class JedisFactory { private static JedisPool jedisPool; public JedisFactory() { super(); } static { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxActive(50000); config.setMaxIdle(10000); config.setMaxWait(10000); config.setTestOnBorrow(true); jedisPool = new JedisPool(config, "XXX.XXX.XXX.XXX",6379,10000); } public Jedis getJedisInstance() { Jedis jedis = jedisPool.getResource(); //jedis.auth("love7road"); return jedis; } import java.util.UUID; import redis.clients.jedis.Jedis; /** * @Company:www.shopin.net User: minxr * Date: 11-9-9 * Time: 下午5:44 */ public class Test { public void testThread() { long begin = System.currentTimeMillis(); Thread thread[] = new Thread[5000]; for (int i = 0; i < thread.length; i++) { thread[i] = new TestThread(); thread[i].start(); } long end = System.currentTimeMillis(); System.out.println("线程执行时间是:" + (end - begin) + " ms"); } public void insertActiveCode() { JedisFactory factory = new JedisFactory(); Jedis jedis = factory.getJedisInstance(); //先向key java framework中存放三条数据 for (int i = 0; i < 10000; i++) { jedis.rpush("activeCode", UUID.randomUUID().toString()); } factory.release(jedis); } public static void main(String args[]) { Test test = new Test(); test.insertActiveCode(); test.testThread(); } class TestThread extends Thread { @Override public void run() { JedisFactory factory = new JedisFactory(); Jedis jedis = factory.getJedisInstance(); String code = jedis.rpop("activeCode"); System.out.println("激活码:" + code); System.out.println("长度:" + jedis.llen("activeCode")); System.out.println("#############################"); factory.release(jedis); } } } /** * 配合使用getJedisInstance方法后将jedis对象释放回连接池中 * * @param jedis 使用完毕的Jedis对象 * @return true 释放成功;否则返回false */ public boolean release(Jedis jedis) { if (jedisPool != null && jedis != null) { jedisPool.returnResource(jedis); return true; } return false; } }
2 楼
dilaomi123
2012-05-07
还有个问题,ShardedJedisPool 这个是如何用的?哪里有对应的资料啊,兄弟,我急需!非常感谢
3 楼
dilaomi123
2012-05-07
我的qq:11210999 希望能获得您的帮助!
4 楼
lhc1002
2012-05-16
楼上哥们,我按LZ描述所说的对阀门进行了设置,线程只要超过100也会报Could not get a resource from the pool ,这个问题你解决了吗?还望指教。
5 楼
jiasky
2012-05-16
dilaomi123 写道 你好~~~看了您的文章收益匪浅,我也遇到类似的问题,但是我设置了阀值以后,同时跑5000个线程去取数据,还是报同样的错误,非常郁闷.还请不吝啬赐教,不胜感激 package com.sz7road.web.action.online.user; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class JedisFactory { private static JedisPool jedisPool; public JedisFactory() { super(); } static { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxActive(50000); config.setMaxIdle(10000); config.setMaxWait(10000); config.setTestOnBorrow(true); jedisPool = new JedisPool(config, "XXX.XXX.XXX.XXX",6379,10000); } public Jedis getJedisInstance() { Jedis jedis = jedisPool.getResource(); //jedis.auth("love7road"); return jedis; } import java.util.UUID; import redis.clients.jedis.Jedis; /** * @Company:www.shopin.net User: minxr * Date: 11-9-9 * Time: 下午5:44 */ public class Test { public void testThread() { long begin = System.currentTimeMillis(); Thread thread[] = new Thread[5000]; for (int i = 0; i < thread.length; i++) { thread[i] = new TestThread(); thread[i].start(); } long end = System.currentTimeMillis(); System.out.println("线程执行时间是:" + (end - begin) + " ms"); } public void insertActiveCode() { JedisFactory factory = new JedisFactory(); Jedis jedis = factory.getJedisInstance(); //先向key java framework中存放三条数据 for (int i = 0; i < 10000; i++) { jedis.rpush("activeCode", UUID.randomUUID().toString()); } factory.release(jedis); } public static void main(String args[]) { Test test = new Test(); test.insertActiveCode(); test.testThread(); } class TestThread extends Thread { @Override public void run() { JedisFactory factory = new JedisFactory(); Jedis jedis = factory.getJedisInstance(); String code = jedis.rpop("activeCode"); System.out.println("激活码:" + code); System.out.println("长度:" + jedis.llen("activeCode")); System.out.println("#############################"); factory.release(jedis); } } } /** * 配合使用getJedisInstance方法后将jedis对象释放回连接池中 * * @param jedis 使用完毕的Jedis对象 * @return true 释放成功;否则返回false */ public boolean release(Jedis jedis) { if (jedisPool != null && jedis != null) { jedisPool.returnResource(jedis); return true; } return false; } } 我也比较懊恼,我做了调整之后,经测试偶尔也会出现此异常。
6 楼
jiasky
2012-05-16
dilaomi123 写道 还有个问题,ShardedJedisPool 这个是如何用的?哪里有对应的资料啊,兄弟,我急需!非常感谢 而且我新增了一个redis实例之后问题依旧,初步怀疑是redis server的实现bug. |
|