Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法从池中获取资源(SocketTimeoutException:)_Java_Redis_Socketexception_Jedis - Fatal编程技术网

Java 无法从池中获取资源(SocketTimeoutException:)

Java 无法从池中获取资源(SocketTimeoutException:),java,redis,socketexception,jedis,Java,Redis,Socketexception,Jedis,我正在运行多个工作线程(大约10个)来访问redis Q中的数据。 对于我正在使用的绝地客户端的infinte超时 Jedis jedis = pool.getResource(); jedis.getClient().setTimeoutInfinite(); 我仍然收到错误“无法从池中获取资源”。堆栈跟踪如下所示 redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from

我正在运行多个工作线程(大约10个)来访问redis Q中的数据。
对于我正在使用的绝地客户端的infinte超时

Jedis jedis = pool.getResource();
jedis.getClient().setTimeoutInfinite();  
我仍然收到错误“无法从池中获取资源”。
堆栈跟踪如下所示

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:22)
at Workers.Worker1.met1(Worker1.java:124)
at Workers.Worker1.work(Worker1.java:108)
at org.gearman.impl.worker.WorkerConnectionController$3.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)  

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out
at redis.clients.jedis.Connection.connect(Connection.java:124)
at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:54)
at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1657)
at redis.clients.jedis.JedisPool$JedisFactory.makeObject(JedisPool.java:63)
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1188)
at redis.clients.util.Pool.getResource(Pool.java:20)
... 6 more  

Caused by: java.net.SocketTimeoutException: connect timed out
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:119)
... 11 more

不确定,但也许你没有将绝地武士的物品返回池中,而且你的redis服务器有连接限制

每个工作线程应在其工作完成后将绝地实例返回池中:

Jedis jedis = jedisPool.getResource();
try {
    jedis.getClient().setTimeoutInfinite();
    // your code here...
    ...
} finally {
    jedisPool.returnResource(jedis);
}

我注意到,如果Redis没有运行,这个异常可以也将被抛出。请注意。

如果您的代码如下所示:

JedisPoolConfig jedisPoolConfig = initPoolConfig();    
jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379);  
您可以尝试以下方法:

JedisPoolConfig jedisPoolConfig = initPoolConfig();    
jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379,10*1000); 

这是因为对于Redis,默认超时时间是2秒,但程序可能已经在这段时间内完成了运行。

根据Rick Hanlon的回答,如果将Redis与Spring Boot一起使用,也会引发此异常

如果您使用的是SpringBoot,那么仅仅依赖Redis是不够的;您还需要从手动下载Redis并在计算机上安装,然后在Bash终端上运行:

me@my_pc:/path/to/redis/dir$ ./src/redis-server ./redis.conf
运行服务器后,您需要在所有使用Redis的应用程序中添加相关行:

application.properties

...
spring.redis.host: <yourhost> // usually localhost, but can also be on a LAN
spring.redis.port: <yourport> // usually 6379, but settable in redis.conf

这是经常发生还是偶尔发生?如果是偶然的,您可能需要检查连接池的大小

如果使用的是
config
,则默认连接池大小为。这对你的案子来说可能太小了

JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128);
jedisPool = new JedisPool(poolConfig, HOST, PORT, ...);
可能的原因

1-Redis服务器关闭或Redis应用程序没有响应

2-应用程序无法连接到Redis服务器(防火墙等问题)

3-与Redis服务器的连接超时

(Redis)池中的所有连接当前都很忙,无法分配新连接

案例1和案例2与下文相关

对于情况3,必须增加连接超时(“RedConnectionTimeout”):

对于情况4,必须增加最大连接计数(“RedisMaximumActiveConnectionCount”):

假设以下或类似实施

private Pool<Jedis> pool =  null;   

private final String RedisIp="10.10.10.11";
private final int RedisPort=6379;
private final String RedisConnectionTimeout=2000;
private final String RedisMaximumWaitTime=1000;
private final String RedisMaximumIdleConnectionCount=20;
private final String RedisMaximumActiveConnectionCount=300;
private final String SentinelActive=false;
private final String SentinelHostList="10.10.10.10:26379,10.10.10.10:26380,10.10.10.10:26381";
private final String SentinelMasterName="sentinel-master-name";

private synchronized void initializePool()
{
    if(pool!=null) return;

    poolConfig poolConfig = new poolConfig();
    poolConfig.setMaxTotal(RedisMaximumActiveConnectionCount); 
    poolConfig.setMaxIdle(RedisMaximumIdleConnectionCount);  
    poolConfig.setMaxWaitMillis(RedisMaximumWaitTime); 

    if(SentinelActive)
    {
        String [] sentinelsArray = SentinelHostList.split(",");

        Set<String> sentinels = new HashSet<>();            
        for(String sentinel : sentinelsArray)
        {
            sentinels.add(sentinel);
        }

        String masterName = SentinelMasterName;

        pool = new JedisSentinelPool(masterName, sentinels, poolConfig, RedisConnectionTimeout);            
    }
    else
    {       
        pool = new pool(poolConfig, RedisIp, RedisPort, RedisConnectionTimeout);
    }

}           

protected Jedis getConnection()
{               
    if(pool==null)
        initializePool();

      Jedis jedis = pool.getResource();

      return jedis;     
}   
private Pool=null;
私有最终字符串redisp=“10.10.10.11”;
私人最终int再报告=6379;
私有最终字符串RedisConnectionTimeout=2000;
私有最终字符串RedisMaximumWaitTime=1000;
私有最终字符串RedisMaximumIdleConnectionCount=20;
私有最终字符串RedisMaximumActiveConnectionCount=300;
私有最终字符串sentinelative=false;
私有最终字符串SentinelHostList=“10.10.10.10:26379,10.10.10.10:26380,10.10.10.10:26381”;
私有最终字符串SentinelMasterName=“sentinel master name”;
私有同步的void initializePool()
{
if(pool!=null)返回;
poolConfig-poolConfig=new-poolConfig();
poolConfig.setMaxTotal(RedisMaximumActiveConnectionCount);
poolConfig.setMaxIdle(RedisMaximumIdleConnectionCount);
poolConfig.setMaxWaitMillis(RedisMaximumWaitTime);
if(前哨)
{
字符串[]sentinelsArray=SentinelHostList.split(“,”);
Set sentinels=new HashSet();
用于(字符串sentinel:sentinelsArray)
{
哨兵。添加(哨兵);
}
字符串masterName=SentinelMasterName;
pool=新的JedisSentinelPool(主机名、哨兵、poolConfig、RedisConnectionTimeout);
}
其他的
{       
pool=新池(poolConfig、redisp、RedisPort、RedisConnectionTimeout);
}
}           
受保护的绝地武士
{               
如果(池==null)
initializePool();
绝地武士=pool.getResource();
返回绝地;
}   

当绝地武士根本无法到达所需的redis实例(域/ip、端口或密码)时,我就遇到了这个错误,如果他们错了,或者他们以前是对的,现在是错的,或者他们是对的,但防火墙阻止了对他们的访问,等等,就会发生这个错误

我知道OP已经确认运行了redis cli来确认连接,但如果确认这是从jedis呼叫的同一个地方(可能是一个应用服务器,利用jedis连接到某个redis服务器)完成的,那会很有帮助


但那篇原始帖子是2012年发布的,所以我不希望听到更新,但我把这些留给可能找到这篇帖子的其他人。

你的Redis服务器还活着吗?您可以使用redis cli从客户端连接到它吗?是的,redis服务器处于活动状态,并且可以使用redis cli连接。我也有同样的问题。Redis正在运行。使用JedisPool时会出现问题,我会
returnResource
。绝地武士=新绝地武士(“本地主机”)。你解决这个问题了吗?是的@Jarek,我已经把资源还给你了。返回资源池(绝地);pool.destroy();在我的Java应用程序中,我使用的是Jedis2.0.0.jar文件,redis服务器版本是2.4.13。是它造成了问题吗?
returnResource
是受保护的方法,您不能使用它。您需要使用try with resources
try(Jedis Jedis=pool.getResource()){}
您能指导我吗?即使连接到远程redis实例,也需要安装redis吗?
pool = new pool(poolConfig, RedisIp, RedisPort, RedisConnectionTimeout);
poolConfig.setMaxTotal(RedisMaximumActiveConnectionCount); 
private Pool<Jedis> pool =  null;   

private final String RedisIp="10.10.10.11";
private final int RedisPort=6379;
private final String RedisConnectionTimeout=2000;
private final String RedisMaximumWaitTime=1000;
private final String RedisMaximumIdleConnectionCount=20;
private final String RedisMaximumActiveConnectionCount=300;
private final String SentinelActive=false;
private final String SentinelHostList="10.10.10.10:26379,10.10.10.10:26380,10.10.10.10:26381";
private final String SentinelMasterName="sentinel-master-name";

private synchronized void initializePool()
{
    if(pool!=null) return;

    poolConfig poolConfig = new poolConfig();
    poolConfig.setMaxTotal(RedisMaximumActiveConnectionCount); 
    poolConfig.setMaxIdle(RedisMaximumIdleConnectionCount);  
    poolConfig.setMaxWaitMillis(RedisMaximumWaitTime); 

    if(SentinelActive)
    {
        String [] sentinelsArray = SentinelHostList.split(",");

        Set<String> sentinels = new HashSet<>();            
        for(String sentinel : sentinelsArray)
        {
            sentinels.add(sentinel);
        }

        String masterName = SentinelMasterName;

        pool = new JedisSentinelPool(masterName, sentinels, poolConfig, RedisConnectionTimeout);            
    }
    else
    {       
        pool = new pool(poolConfig, RedisIp, RedisPort, RedisConnectionTimeout);
    }

}           

protected Jedis getConnection()
{               
    if(pool==null)
        initializePool();

      Jedis jedis = pool.getResource();

      return jedis;     
}