java redis socketexception jedis

java - No se pudo obtener un recurso del grupo(SocketTimeoutException:)



redis socketexception (6)

¿Ocurrió siempre u ocasionalmente? Si es ocasional, es posible que desee verificar el tamaño de su grupo de conexiones.

El tamaño predeterminado de la agrupación de conexiones, si está utilizando JedisPoolConfig , es 8 . Esto podría ser demasiado pequeño para su caso.

JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(128); jedisPool = new JedisPool(poolConfig, HOST, PORT, ...);

Estoy ejecutando varios subprocesos de trabajo (alrededor de 10) para acceder a los datos de la redis Q.
Para el estoy usando infinte timeout para Jedis Client .

Jedis jedis = pool.getResource(); jedis.getClient().setTimeoutInfinite();

Todavía recibo el error "No se pudo obtener un recurso del grupo". El stacktrace se da a continuación.

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


Basado en la respuesta de Rick Hanlon, esta excepción también se lanza si se usa Redis con Spring Boot.

Si está utilizando Spring Boot, la dependencia de Redis no es suficiente; también necesita descargar e instalar manualmente Redis en su máquina desde redis.io , luego ejecutarlo desde un terminal Bash:

me@my_pc:/path/to/redis/dir$ ./src/redis-server ./redis.conf

Después de ejecutar el servidor, deberá agregar las líneas relevantes en todas las aplicaciones que usan 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


No estoy seguro, pero tal vez no devuelva los objetos Jedis al grupo, y su servidor redis tiene un límite de conexión.

Cada subproceso de trabajo debe devolver las instancias de Jedis a la agrupación una vez finalizado su trabajo:

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


Noté que esta excepción puede y será lanzada si Redis no se está ejecutando. Sólo un heads up.


Posibles causas;

1 - El servidor Redis está inactivo o la aplicación Redis no responde.

2 - La aplicación no puede conectarse al servidor Redis (problemas de cortafuegos, etc.).

3 - Se agotó el tiempo de espera del servidor Redis.

4 - Todas las conexiones en el grupo (Redis) están ocupadas actualmente, no se puede asignar una nueva conexión.

Los casos 1 y 2 están relacionados con la infraestructura.

Para el caso 3, se debe aumentar el tiempo de espera de conexión ("RedisConnectionTimeout"):

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

Para el caso 4, se debe aumentar el recuento máximo de conexiones ("RedisMaximumActiveConnectionCount"):

poolConfig.setMaxTotal(RedisMaximumActiveConnectionCount);

Asumiendo la siguiente implementación o similar;

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


Si tu código es así:

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

Puedes probar esto:

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

Esto se debe a que, para Redis, el tiempo de espera predeterminado es de 2 segundos, pero es posible que el programa haya terminado de ejecutarse en este tiempo.