2012-10-24 14 views
13

che sto esecuzione di più thread di lavoro (circa 10) per accedere ai dati dal Redis Q.
Per la sto usando timeout infinte per Jedi client .Impossibile ottenere una risorsa dal pool (SocketTimeoutException :)

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

Ancora sto ottenendo l'errore "Impossibile ottenere una risorsa dal pool". Lo stacktrace è indicato di seguito.

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 
+0

E il server Redis è attivo? Puoi collegarti dal box del cliente usando redis-cli? –

+0

Sì Il server Redis è attivo e può connettersi utilizzando redis-cli – Vignesh

+1

Ho lo stesso problema. Redis è in esecuzione. Il problema si verifica quando si utilizza JedisPool e si esegue 'returnResource'. Nessun problema con 'Jedis jedis = new Jedis (" localhost ");'. Hai risolto questo problema? –

risposta

1

Non sicuro, ma forse non si restituiscono oggetti Jedis al pool e il server redis ha il limite di connessione.

Ogni thread di lavoro deve restituire le istanze Jedi alla piscina dopo il suo lavoro è completo:

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

sì @Jarek, sto già restituendo la risorsa. \t ** pool.returnResource (jedis); piscina.destroy(); ** – Vignesh

+0

Nella mia app Java sto usando il file Jedis2.0.0.jar e la versione del server redis è 2.4.13. Sta facendo il problema? – Vignesh

4

ho notato che questa eccezione può essere e sarà generata se Redis non è in esecuzione. Solo un avviso.

1

Se il codice è simile a questo:

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

si può provare questo:

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

Questo perché per Redis il tempo di timeout predefinito è di 2 secondi, ma il programma potrebbe essere terminato l'esecuzione In questo momento.

2

In base alla risposta di Rick Hanlon, questa eccezione viene generata anche se si utilizza Redis con Spring Boot.

Se si utilizza Spring Boot, solo la dipendenza di Redis non è sufficiente; è inoltre necessario scaricare e installare manualmente Redis sulla vostra macchina da redis.io, quindi eseguirlo fuori di un terminale Bash:

[email protected]_pc:/path/to/redis/dir$ ./src/redis-server ./redis.conf 

Dopo l'esecuzione il server, è necessario aggiungere le linee in questione in tutte le applicazioni che uso 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 
0

È successo sempre o occasionalmente? Se è stato occasionale, potresti voler controllare la dimensione del tuo pool di connessioni.

La dimensione del pool di connessione predefinita, se si utilizza JedisPoolConfig, è 8. Questo potrebbe essere troppo piccolo per il tuo caso.

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