使用redis会报Could not get a resource from the pool

qq_15153891 2017-03-24 06:21:26
使用spring data redis的时候 会报Could not get a resource from the pool 百度试了下发现不能解决问题

配置如下
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="1024"></property>
<property name="maxIdle" value="10"></property>
<property name="maxWaitMillis" value="3000"></property>
<property name="minEvictableIdleTimeMillis" value="300000"></property>
<property name="numTestsPerEvictionRun" value="3"></property>
<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
<property name="testOnBorrow" value="true"></property>
<property name="testOnReturn" value="true"></property>
<property name="testWhileIdle" value="true"></property>
</bean>


ApplicationContext applicationContext = applicationContext = new ClassPathXmlApplicationContext("applicationContext-redis.xml");
StringRedisTemplate stringRedisTemplate = applicationContext.getBean(StringRedisTemplate.class);
RedisTemplate redisTemplate = (RedisTemplate)applicationContext.getBean("redisTemplate");
ValueOperations<String,String> redis = redisTemplate.opsForValue();
System.out.println(redis.get("test"));

for (int i=0; i<3000; i++) {
ThreadT t = new ThreadT();
t.setRedisTemplate(redisTemplate);
t.start();
}



class ThreadT extends Thread {

RedisTemplate redisTemplate;

public void run() {
while(true) {
ValueOperations<String,String> redis = redisTemplate.opsForValue();
System.out.println(redis.get("test"));
}
}

public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
}


求大神解释一下

Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at redis.clients.jedis.Connection.connect(Connection.java:136)
... 18 more
Exception in thread "Thread-1781" org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
2017-03-24 18:08:49,400 [Thread-2244] DEBUG [RedisConnectionUtils:204] - Closing Redis Connection
2017-03-24 18:08:49,400 [Thread-1454] DEBUG [RedisConnectionUtils:125] - Opening RedisConnection
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:162)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:251)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:58)
at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:128)
at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:91)
at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:78)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:178)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:153)
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:86)
2017-03-24 18:08:49,400 [Thread-2516] DEBUG [RedisConnectionUtils:204] - Closing Redis Connection
at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:43)
at cn.slimsmart.redis.ThreadT.run(TestMain.java:34)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:42)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:155)
... 10 more
2017-03-24 18:08:49,400 [Thread-2272] DEBUG [RedisConnectionUtils:204] - Closing Redis Connection
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused: connect
at redis.clients.jedis.Connection.connect(Connection.java:141)
at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:75)
at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1716)
at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:65)
at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:819)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:429)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:360)
at redis.clients.util.Pool.getResource(Pool.java:40)
... 11 more
...全文
21036 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
iioSnail 2019-09-06
  • 打赏
  • 举报
回复
我和你遇到了差不多的问题,然后我解决了,写了一篇博客,其他人可以参考一下 https://blog.csdn.net/zhaohongfei_358/article/details/100584158
zgycsmb 2019-06-26
  • 打赏
  • 举报
回复
重新启动下redis,再重启动项目,应该是正常的。
  • 打赏
  • 举报
回复
引用 10 楼 taodengwen 的回复:
第一 redis最大连接数要与并数设计要合理
第二 redis链接用完一定要归还到连接池中, 这个很重要!,切记 !! 否则链接一多连接池中的链接就不够用了; 很明显, 贴的代码 链接没有关闭或归还到连接池中!

redis链接 正常关闭或归还到连接池第一种情况一般不会出现Could not get a resource from the pool这个问题,可能会出现获取链接的速度要慢一些
  • 打赏
  • 举报
回复
第一 redis最大连接数要与并数设计要合理
第二 redis链接用完一定要归还到连接池中, 这个很重要!,切记 !! 否则链接一多连接池中的链接就不够用了; 很明显, 贴的代码 链接没有关闭或归还到连接池中!
kingdomzhf 2018-08-27
  • 打赏
  • 举报
回复
还要检查你的应用有没有释放redis链接
紫川琴秀 2018-08-23
  • 打赏
  • 举报
回复


package util;


import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;

import com.system.PublicParameter;



import net.sf.json.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;

public final class RedisUtil{

private static String ADDR = "XXX.XXX.X.XXX";


//Redis的端口号
private static int PORT = 6379;

//访问密码
private static String AUTH = "XXXX";

//可用连接实例的最大数目,默认值为8;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
private static int MAX_ACTIVE = 800;

//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
private static int MAX_IDLE = 100;

//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
private static long MAX_WAIT = 50000;

private static int TIMEOUT = 50000;

//在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
private static boolean TEST_ON_BORROW = true;

public static JedisPool jedisPool = null;

/**
* 初始化Redis连接池
*/
static {
try {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR, PORT,TIMEOUT);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 获取Jedis实例
* @return
*/
public synchronized static Jedis getJedis()
{
int timeoutCount = 0;
while (true) // 如果是网络超时则多试几次
{
try
{
Jedis jedis = jedisPool.getResource();
return jedis;
} catch (Exception e)
{
// 底层原因是SocketTimeoutException,不过redis已经捕捉且抛出JedisConnectionException,不继承于前者
if (e instanceof JedisConnectionException || e instanceof SocketTimeoutException)
{
timeoutCount++;
System.out.println("getJedis timeoutCount="+timeoutCount);
if (timeoutCount > 3)
{
break;
}
}else
{

break;
}
}
}
return null;
}
/**
* 释放jedis资源
* @param jedis
*/
public static void returnResource(final Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}


public static void mset(String key,String value){
Jedis redis = getJedis();
try {
redis.set(key, value);
} catch (Exception e) {
e.printStackTrace();
}finally{
jedisPool.returnResource(redis);
}

}

public static String mget(String co_make,String key){
Jedis redis = getJedis();
String value="";
try {

if(key.equals("")){
value=redis.get(co_make);
}else{
if(redis.get(co_make)!=null){
net.sf.json.JSONObject json1 = net.sf.json.JSONObject.fromObject(redis.get(co_make).toString());
if(json1.get(key)!=null){
value=json1.getString(key);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
jedisPool.returnResource(redis);
}

return setNullToBanlk(value);
}



public static String mget(String key){
Jedis redis = getJedis();
String value="";
try {
value=redis.get(key);
} catch (Exception e) {
e.printStackTrace();
}finally{
jedisPool.returnResource(redis);
}

return setNullToBanlk(value);
}

public static void mdel(String key){
Jedis redis = getJedis();
try {
redis.del(key);
} catch (Exception e) {
e.printStackTrace();
}finally{
jedisPool.returnResource(redis);
}

}




public static String setNullToBanlk(String name) {
if (name == null) {
name = "";
}
return name != null ? name.trim() : "";
}
public RedisUtil() {

}
public static void main(String[] args) {
for (int i = 0; i < 3000; i++) {
new Thread(new Runnable() {

public void run() {
Jedis redis = getJedis();
try {
for (int i = 0; i < 1000; i++) {
redis.mset("a", "1");
System.out.println("线程1成功==="+i);
}
} catch (Exception e) {
e.printStackTrace();
}

}
}).start();
}







}



}

用我的这个配置吧,10000个线程都不会出问题
qq_32040927 2018-08-22
  • 打赏
  • 举报
回复
引用 6 楼 flyfeifei66 的回复:
最大1024个链接,你开了3000个线程,这是从哪里搞来的例子吧,肯定不够用。因为每个线程都是死循环,抓住链接不放。但是你的机器开这个多线程CPU肯定不够用,我猜这个程序,运行了一点时间才报的错。
楼上说的有可能 线程数太大了
济南大飞哥 2018-08-06
  • 打赏
  • 举报
回复
最大1024个链接,你开了3000个线程,这是从哪里搞来的例子吧,肯定不够用。因为每个线程都是死循环,抓住链接不放。但是你的机器开这个多线程CPU肯定不够用,我猜这个程序,运行了一点时间才报的错。
Cx_轩 2017-06-08
  • 打赏
  • 举报
回复
http://blog.csdn.net/qq_25223941/article/details/72911270
点滴寸土 2017-05-15
  • 打赏
  • 举报
回复
1、你的redis服务器配置的连接数是多少? 2、你的并发很大吗,对redis操作很多吗?
X元素 2017-04-07
  • 打赏
  • 举报
回复
redis连接数量超过本身设置的最大值了。
GrayHJX 2017-04-06
  • 打赏
  • 举报
回复
同问,偶尔会发现是这样,怀疑是线程池的设置问题
招式 2017-03-27
  • 打赏
  • 举报
回复
绑定的地址修改了吗,保护模式关闭了吗
db服务器连接mysql+redis高可用高性能框架干货1、使用c++语言,vs2019开发垮平台[windows和linux]连接MySql和redis框架。2、使用MySql持久化玩家数据,redis做玩家数据缓存层,redis不做数据持久化。mysql搭配redis工作效率非常高效,就好比男女搭配干活不累,没有redis,mysql也能独立很好的完成用户读写请求。有了redis,用户访问数据的效率更高,时间更短,快速的完成请求。3、讲解如何保持mysql和redis数据强一致性策略,并在代码里实现。每次启动redis,使用管道技术,从mysql批量导入活跃用户数据到redis中,并设置过期时间.4、教程使用线程池技术,每个线程拥有自己独立的数据,线程绑定类。每一个实例就包含一个线程每个线程数据里包含:mysql连接器、redis连接器、内存回收池、安全的串行队列、条件变量、互斥量保证线程内的数据安全。5、工作原理:没有请求时,各个工作线程处于休眠状态。有读写请求时,从线程池获取一个线程,添加读写请求,把数据推送到线程工作队列中。然后工作线程获取队列的数据,进行串行工作任务安排,进行mysql数据库读写操作,以及redis读写数据操作,当完成工作任务时,执行下一个工作任务,同时把处理结果推送到逻辑线程,把数据给用户。6、用户读数据策略:用户获取数据首先是先从redis查找数据,redis命中,返回数据给玩家,redis命中失败,mysql中查找数据,然后写入数据到redis中,返回数据给用户。7、用户写数据策略:用户先从redis中删除数据,然后写数据到mysql中,最后再把数据写入到redis中,保持数据一致性。8、教程是一个干货教程,不是新手教程,mysql基础语法讲解的少,redis有讲解基础系列。教程讲解的是如何搭建一个支持高并发,高性能的读写数据库框架,使用mysql+redis搭配的高可用、高性能框架。该套框架在多个项目使用过,也在棋牌类项目里面使用过。

25,985

社区成员

发帖
与我相关
我的任务
社区描述
高性能WEB开发
社区管理员
  • 高性能WEB开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧