Не удалось получить ресурс из пула (SocketTimeoutException :)

Я запускаю несколько рабочих потоков (около 10) для доступа к данным из Redis Q.
Для этого я использую бесконечный тайм-аут для Jedis Client.

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

person Vignesh    schedule 24.10.2012    source источник
comment
А ваш сервер Redis жив? Можете ли вы подключиться к нему из клиентского ящика с помощью redis-cli?   -  person Didier Spezia    schedule 24.10.2012
comment
Да Сервер Redis жив и может подключаться с помощью redis-cli   -  person Vignesh    schedule 25.10.2012
comment
У меня точно такая же проблема. Redis запущен. Проблема возникает при использовании JedisPool, а я делаю returnResource. Нет проблем с Jedis jedis = new Jedis("localhost");. Вы решили эту проблему?   -  person Vladimir Prudnikov    schedule 22.12.2013


Ответы (7)


Я заметил, что это исключение может и будет выдано, если Redis не запущен. Просто предупреждаю.

person Rick Hanlon II    schedule 17.07.2013

Основываясь на ответе Рика Хэнлона, это исключение также возникает при использовании Redis с Spring Boot.

Если вы используете Spring Boot, просто зависимости Redis недостаточно; вам также необходимо вручную загрузить и установить Redis на свой компьютер из redis.io, а затем запустить его из терминала 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

application.yml:

...
spring:
  redis:
    host: <yourhost> // usually localhost, but can also be on a LAN
    port: <yourport> // usually 6379, but settable in redis.conf
person cst1992    schedule 23.03.2016
comment
Требуется ли установка Redis, даже при подключении к удаленному экземпляру Redis? - person zookastos; 29.05.2021

Это случалось всегда или время от времени? Если это было случайно, вы можете проверить размер пула подключений.

Размер пула соединений по умолчанию, если вы используете JedisPoolConfig, составляет 8. Это может быть слишком мало для вашего случая.

JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128);
jedisPool = new JedisPool(poolConfig, HOST, PORT, ...);
person Devs love ZenUML    schedule 01.03.2017
comment
Не могли бы вы помочь мне stackoverflow.com/questions/51408969/? - person Jeff Cook; 18.07.2018

Возможные причины;

1 - Сервер Redis не работает или приложение Redis не отвечает.

2 - Приложение не может подключиться к серверу Redis (проблемы с брандмауэром и т. Д.).

3 - Истекло время ожидания подключения к серверу Redis.

4 - Все соединения в пуле (Redis) в настоящее время заняты, новое соединение не может быть выделено.

Случаи 1 и 2 связаны ниже.

Для случая 3 необходимо увеличить время ожидания соединения ("RedisConnectionTimeout"):

pool = new pool(poolConfig, RedisIp, RedisPort, RedisConnectionTimeout);

Для случая 4 необходимо увеличить максимальное количество подключений ("RedisMaximumActiveConnectionCount"):

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;     
}   
person Murat    schedule 23.01.2019

Если ваш код такой:

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

Вы можете попробовать это:

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

Это связано с тем, что для Redis время ожидания по умолчанию составляет 2 секунды, но программа могла завершить работу за это время.

person zks    schedule 27.03.2015

Не уверен, но, возможно, вы не возвращаете объекты Jedis в пул, а ваш redis-сервер имеет ограничение на количество подключений.

Каждый рабочий поток должен возвращать экземпляры Jedis в пул после завершения своей работы:

Jedis jedis = jedisPool.getResource();
try {
    jedis.getClient().setTimeoutInfinite();
    // your code here...
    ...
} finally {
    jedisPool.returnResource(jedis);
}
person Jarek    schedule 25.10.2012
comment
да @Jarek, уже возвращаю ресурс. pool.returnResource (джедаи); pool.destroy (); - person Vignesh; 26.10.2012
comment
В моем приложении Java я использую файл Jedis2.0.0.jar, а версия сервера Redis - 2.4.13. Это создает проблему? - person Vignesh; 26.10.2012
comment
returnResource - это защищенный метод, вы не можете его использовать. Вам нужно использовать try с ресурсами try (Jedis jedis = pool.getResource()) {} - person Maciej Dzikowicki; 08.01.2020

Я получил эту ошибку, когда джедаи просто не могли достичь желаемого экземпляра Redis (домен / IP, порт или пароль), что могло произойти, если они были либо неправильными, либо они были правы раньше, а теперь ошибаются, или если они верно, но брандмауэр блокирует к ним доступ и т. д.

Я знаю, что OP подтвердил запуск redis-cli для подтверждения соединения, но было бы полезно подтвердить, было ли это сделано из того же места, откуда исходил вызов джедаев (который мог быть сервером приложений, использующим джедаев для подключения к какой-то сервер Redis).

Но этот исходный пост был написан в 2012 году, поэтому я не ожидаю услышать обновление, но оставляю его для других, кто может найти эту ветку.

person charlie arehart    schedule 27.10.2020