Cant connect to Redis using Jedis after JedisConnectionException.
See original GitHub issueHi, In my application(code given below), one thread will always push the data to the Redis using Jedis with help of Jedispool. The real problem is it will not reconnect automatically to the server after any network outreach, . It throws JedisConnectionException if my server is down. In the try-catch block, I handle this using returnBrokenResource() .But I got another exception while using retrunbrokensource() method. Please correct me anything wrong?
JedisFactory.java
package com.mySample;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig;
class JedisFactory { private static JedisPool jedisPool; private static JedisFactory instance = null;
public JedisFactory() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool(poolConfig, REDIS_HOST, 6379);
}
public JedisPool getJedisPool() {
return jedisPool;
}
public static JedisFactory getInstance() {
if (instance == null) {
instance = new JedisFactory();
}
return instance;
}
}
TestJedis.java
package com.mySample;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis; import redis.clients.jedis.exceptions.JedisConnectionException;
public class TestJedis {
private static final Logger LOGGER = Logger.getLogger(TestJedis.class);
private Jedis jedis = null;
JedisFactory jedisFactory = null;
public TestJedis() {
this.jedis = JedisFactory.getInstance().getJedisPool().getResource();
}
public void push() {
try {
LOGGER.info("Server is running: " + jedis.ping());
if (jedis.isConnected()) {
LOGGER.info("connected");
}
jedis.set("test", "set");
} catch (JedisConnectionException jex) {
LOGGER.info("Got jedis conncetion exception ", jex);
try {
JedisFactory.getInstance().getJedisPool().returnBrokenResource(jedis);
} catch (Exception e) {
LOGGER.info("jedis returnBrokenResource Exception**********", e);
}
} finally {
try{
if(null != jedis)
JedisFactory.getInstance().getJedisPool().returnResource(jedis);
} catch (Exception e) {
LOGGER.info("jedis returnResource Exception**********", e);
}
}
}
}
JedisThread.java
package com.mySample;
public class JedisThread {
public static void main(String args[]) {
new ThreadTest().start();
}
}
class ThreadTest extends Thread { public ThreadTest() { super(); }
public void run() {
TestJedis jedis = new TestJedis();
while (true) {
try {
jedis.push();
} catch (Exception e) {
System.out.println("Got exception");
}
}
}
}
While I executing the code, (Redis server is running), I got following error:
INFO : com.mySample.TestJedis - Server is running: PONG INFO : com.mySample.TestJedis - connected INFO : com.mySample.TestJedis - jedis returnResource Exception********** redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool at redis.clients.util.Pool.returnResourceObject(Pool.java:54) at redis.clients.jedis.JedisPool.returnResource(JedisPool.java:91) at com.mySample.TestJedis.push(TestJedis.java:39) at com.mySample.ThreadTest.run(JedisThread.java:19) Caused by: java.lang.IllegalStateException: Object has already been retured to this pool or is invalid at org.apache.commons.pool2.impl.GenericObjectPool.returnObject(GenericObjectPool.java:582) at redis.clients.util.Pool.returnResourceObject(Pool.java:52) … 3 more
Suppose if I stop the redis server, then error is:
INFO : com.mySample.TestJedis - jedis returnResource Exception********** redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Socket closed at redis.clients.jedis.Connection.flush(Connection.java:70) at redis.clients.jedis.Connection.getAll(Connection.java:243) at redis.clients.jedis.Connection.getAll(Connection.java:238) at redis.clients.jedis.BinaryJedis.resetState(BinaryJedis.java:1733) at redis.clients.jedis.JedisPool.returnResource(JedisPool.java:90) at com.mySample.TestJedis.push(TestJedis.java:39) at com.mySample.ThreadTest.run(JedisThread.java:19) Caused by: java.net.SocketException: Socket closed at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:116) at java.net.SocketOutputStream.write(SocketOutputStream.java:153) at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:31) at redis.clients.util.RedisOutputStream.flush(RedisOutputStream.java:223) at redis.clients.jedis.Connection.flush(Connection.java:68) … 6 more
Issue Analytics
- State:
- Created 9 years ago
- Comments:5
@jijojose1691 I’ve found a problem in your example. The
TestJedis
class is always using the same instance of Jedis as it’s being instantiated in the class constructor. That’s why you’re receiving exceptions when trying to return the broken resource because that Jedis instance was already returned before.You need put the following line
this.jedis = JedisFactory.getInstance().getJedisPool().getResource();
inside your push method so you get a new jedis instance each time the method is called.Give it a try and let us know the results.
@marcosnils I met a similar problem, (redis version is 3.0.5, jedis version is 2.7.2): redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool at redis.clients.util.Pool.returnBrokenResourceObject(Pool.java:85) at redis.clients.jedis.JedisPool.returnBrokenResource(JedisPool.java:98) at redis.clients.jedis.JedisPool.returnResource(JedisPool.java:113) at redis.clients.jedis.JedisClusterConnectionHandler.returnConnection(JedisClusterConnectionHandler.java:20) at redis.clients.jedis.JedisClusterCommand.releaseConnection(JedisClusterCommand.java:95) at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:85) at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:29) at redis.clients.jedis.JedisCluster.hincrBy(JedisCluster.java:381) … Caused by: java.lang.IllegalStateException: Invalidated object not currently part of this pool at org.apache.commons.pool2.impl.GenericObjectPool.invalidateObject(GenericObjectPool.java:643) at redis.clients.util.Pool.returnBrokenResourceObject(Pool.java:83) … 16 more