Cannot get Jedis connection; Could not get a resource from the pool

橙三吉。 提交于 2019-12-06 06:06:10

问题


I am running a batch job for every 5 minutes and I don't wanna other nodes to run the same job hence I am using Jedis lock to lock an object for 5 minutes. So that other node won't get the lock if they try to run the same job. Job started after acquiring the lock and when I try to read it from Redis I am getting the following exception saying

'Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at redis.clients.util.Pool.getResource(Pool.java:53)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:194)
    ... 40 more
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    at redis.clients.jedis.Connection.disconnect(Connection.java:224)
    at redis.clients.jedis.BinaryClient.disconnect(BinaryClient.java:941)
    at redis.clients.jedis.Connection.close(Connection.java:214)
    at redis.clients.jedis.BinaryClient.close(BinaryClient.java:947)
    at redis.clients.jedis.Jedis.close(Jedis.java:3412)
    at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:117)
    at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:836)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:434)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
    at redis.clients.util.Pool.getResource(Pool.java:49)'

This is what the code I have

@Bean
public Jedis getJedis()
{
    Jedis jedis = new Jedis(this.redisHost, nteger.valueOf(this.redisPort));
    jedis.auth(this.redisPassword);
    return jedis;
}

spring-boot Application.properties file

# DATA REDIS
spring.data.redis.repositories.enabled=true
# REDIS (RedisProperties)
spring.redis.host=10.160.49.22
spring.redis.password=qweqewqw
spring.redis.ssl=true 
#spring.redis.pool.max-active=10
#spring.redis.pool.max-idle=10
# spring.redis.pool.max-wait=30000
spring.redis.port=6379

Job executes the following code at the start to get the lock

JedisLock jedisLock = new JedisLock(jedis, getLockName(), getTimeInMillis());
jedisLoc.acquire()

After that redis repository class is trying to read values for a particular pattern..

List<String> hotelCodes = redisTemplate.execute(new RedisCallback<List<String>>() {
            /**
             * Gets called by {@link RedisTemplate} with an active Redis connection. Does not need to care about activating or
             * closing the connection or handling exceptions.
             *
             * @param connection active Redis connection
             * @return a result object or {@code null} if none
             * @throws DataAccessException
             */
            @Override
            public List<String> doInRedis(RedisConnection connection) throws DataAccessException {
                ScanOptions options = ScanOptions.scanOptions().match(pattern).count(1).build();
                Cursor<Map.Entry<byte[], byte[]>> entries = connection.hScan(HASH_KEY.getBytes(), options);
                List<String> result = new ArrayList<>();
                if (entries != null)
                    while (entries.hasNext()) {
                        Map.Entry<byte[], byte[]> entry = entries.next();
                        byte[] actualValue = entry.getValue();
                        result.add(new String(actualValue));
                    }

                return result;
            }
        });
        return hotelCodes;

Then this is the complete exception I see in log.

org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:204)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:348)
    at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:129)
    at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:92)
    at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:79)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:194)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:169)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:157)
    at com.hyatt.pms.jobs.dao.impl.HeartbeatRepositoryImpl.findAll(HeartbeatRepositoryImpl.java:62)
    at com.hyatt.pms.jobs.dao.impl.HeartbeatRepositoryImpl$$FastClassBySpringCGLIB$$e3fe6169.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
    at com.hyatt.pms.jobs.dao.impl.HeartbeatRepositoryImpl$$EnhancerBySpringCGLIB$$68719252.findAll(<generated>)
    at com.hyatt.pms.jobs.processors.HeartbeatTestProcessor.processCluster(HeartbeatTestProcessor.java:54)
    at com.hyatt.pms.jobs.processors.TestProcessor.process(TestProcessor.java:61)
    at com.hyatt.pms.jobs.processors.HeartbeatTestProcessor.process(HeartbeatTestProcessor.java:39)
    at com.hyatt.pms.jobs.processors.HeartbeatTestProcessor$$FastClassBySpringCGLIB$$99fdfbdc.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
    at com.hyatt.pms.jobs.processors.HeartbeatTestProcessor$$EnhancerBySpringCGLIB$$860eb7e4.process(<generated>)
    at com.hyatt.pms.jobs.domain.jobs.HeartbeatJob.runHealthCheck(HeartbeatJob.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call$$$capture(Executors.java:511)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java)
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    at java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at redis.clients.util.Pool.getResource(Pool.java:53)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:194)
    ... 40 more
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    at redis.clients.jedis.Connection.disconnect(Connection.java:224)
    at redis.clients.jedis.BinaryClient.disconnect(BinaryClient.java:941)
    at redis.clients.jedis.Connection.close(Connection.java:214)
    at redis.clients.jedis.BinaryClient.close(BinaryClient.java:947)
    at redis.clients.jedis.Jedis.close(Jedis.java:3412)
    at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:117)
    at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:836)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:434)
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
    at redis.clients.util.Pool.getResource(Pool.java:49)
    ... 43 more
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:757)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
    at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:52)
    at redis.clients.util.RedisOutputStream.flush(RedisOutputStream.java:216)
    at redis.clients.jedis.Connection.disconnect(Connection.java:220)
    ... 52 more

Anyone knows why I get this exception and how to fix it?


回答1:


1.Try to use Jedis connection pool to get Jedis instance instead of using new Jedis(), for that you will have to configure JedisPool in config Since you are using it as bean, you should use JedisPool bean and then get Jedis from it wherever you are supposed to perform an operation and close it after finishing.

2.Otherwise use spring's redisTemplate with config as below

@Bean
public JedisConnectionFactory redisConnectionFactory() {
    JedisConnectionFactory factory = new JedisConnectionFactory();
    factory.setHostName(redisHostName);
    factory.setPort(redisPort);
    factory.setUsePool(true);

    return factory;
}

@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory cf) {
    RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
    redisTemplate.setDefaultSerializer(new StringRedisSerializer());
    redisTemplate.setConnectionFactory(cf);

    return redisTemplate;
}



回答2:


Fetch Jedis instance from spring-managed redis connection pool:

Jedis jedis = (Jedis) redisTemplate.getConnectionFactory().getConnection().getNativeConnection();

Then u can use it to instantiate JedisLock.




回答3:


Change bind 127.0.0.1 to bind {replace with machine ip} in your redis.{os}.conf file of Redis



来源:https://stackoverflow.com/questions/47763245/cannot-get-jedis-connection-could-not-get-a-resource-from-the-pool

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!