Не удалось получить ресурс из пула JedisConnectionException

Привет всем, я пытаюсь настроить сервер Redis с помощью java. Мой сервер Redis - это Linux-сервер с неограниченным ulimit.

Вот мой весенний бин, который создает связь

открытый класс JedisService реализует IJedisService, InitializingBean, DisposableBean {private JedisPool jedisPool;

public JedisService() {

}

public JedisPool getJedisPool() {
    return jedisPool;
}

@Override
public void destroy() throws Exception {
    if(jedisPool != null){
        jedisPool.destroy();
    }

}

@Override
public void afterPropertiesSet() throws Exception {
    JedisPoolConfig poolConfig = new JedisPoolConfig();
    poolConfig.setMaxActive(1000);
    poolConfig.setMaxIdle(10);
    poolConfig.setMinIdle(1);
    poolConfig.setMaxWait(30000);
    poolConfig.setNumTestsPerEvictionRun(10);
    poolConfig.setTestOnBorrow(true);
    poolConfig.setTestOnReturn(true);
    poolConfig.setTestWhileIdle(true);
    poolConfig.setTimeBetweenEvictionRunsMillis(30000);

    jedisPool = new JedisPool(poolConfig,Config.REDIS_HOST,
            RestrictionUtils.REDIS_PORT,RestrictionUtils.REDIS_CONNECTION_TIMEOUT);

}

public boolean validateHitsCount(String hostKey,String urlKey,int hostHitsCount, int urlHitsCount, long timeKey,Map<String, Object> overLimit){
    int retryCount = 0;
    return recursiveRedisConnection(retryCount,hostKey,urlKey,hostHitsCount,urlHitsCount,timeKey,overLimit);
}

private boolean recursiveRedisConnection(int retryCount,String hostKey,String urlKey,int hostHitsCount, int urlHitsCount, long timeKey,Map<String, Object> overLimit){
    Jedis jedis = null;
    boolean returnObj = true;
    try {
        //Connection
        jedis = getJedisPool().getResource();
        jedis.connect();

        //Delete previous keys
        try {
            deletePreviouskeys(jedis, urlKey, hostKey, timeKey);
        } catch (Exception e) {
        }

        //Validation
        String value = jedis.get(hostKey+timeKey);
        if(value != null){
            try {
                int count = Integer.parseInt(value);
                System.out.println("HostCount: "+hostKey+ "    "+count);
                if(count < hostHitsCount){
                    jedis.incr(hostKey+timeKey);
                    returnObj = validateURLHits(jedis, urlKey, urlHitsCount, timeKey, overLimit);
                }else{
                    returnObj = false;
                    overLimit.put("Data", "You have reached maximum limit for hits---"+hostKey);
                }
            } catch (Exception e) {
            }

        }else{
            value = 1+"";
            jedis.set(hostKey+timeKey, value);
            jedis.expire(hostKey+timeKey, 60);
            returnObj = validateURLHits(jedis, urlKey, urlHitsCount, timeKey, overLimit);
        }

    } catch (Exception e) {
        retryCount ++;
        if(retryCount < 3){
            recursiveRedisConnection(retryCount,hostKey,urlKey,hostHitsCount,urlHitsCount,timeKey,overLimit);
        }else{
            e.printStackTrace();
            returnObj = false;
        }
    }finally{
        if(jedis != null && jedis.isConnected()){
            getJedisPool().returnResource(jedis);
        }
    }
    return returnObj;
}

private boolean validateURLHits(Jedis jedis,String urlKey, int urlHitsCount, long timeKey,Map<String, Object> overLimit){
    boolean returnObj = true;
    String value = jedis.get(urlKey+timeKey);
    if(value != null){
        try {
            int count = Integer.parseInt(value);
            System.out.println("URLCount: "+urlKey+ "    "+count);
            if(count < urlHitsCount){
                jedis.incr(urlKey+timeKey);
            }else{
                returnObj = false;
                overLimit.put("Data", "Reached maximum limit of hits for this URL");
            }
        }catch(Exception e){
        }
    }else{
        jedis.set(urlKey+timeKey, 1+"");
        jedis.expire(urlKey+timeKey, 60);
    }
    return returnObj;
}

private void deletePreviouskeys(Jedis jedis,String urlKey, String hostKey, long timeKey){
    /*Set<String> keys = jedis.keys("*");
    for(String key :  keys){
        if(!key.equalsIgnoreCase(urlKey+timeKey)){
            if(!key.equalsIgnoreCase(hostKey+timeKey)){
                jedis.del(key);
            }
        }

    }*/
}

}

В контроллере вызывается метод validateURLHits. Но когда я запускаю этот код в нескольких потоках, я получаю эту ошибку

Вы проверяли, что ваш JedisPool создается только один раз и не более?


person viren    schedule 27.02.2014    source источник


Ответы (1)


Поскольку доступ к вашему компоненту Spring осуществляется через многие потоки, а Jedis не является потокобезопасным, возможно, у вас может быть более одного JedisPool, который возвращает странные экземпляры Jedis или экземпляры jedis, используемые разными потоками одновременно. Каждый поток может иметь локальную копию этого экземпляра JedisPool и / или Jedis, а затем получать от него ошибки.

У вас есть два варианта: вы можете объявить JedisPool как static final (только одно значение для каждого загрузчика классов) или использовать блокировку с двойной проверкой (с изменчивым), чтобы гарантировать, что есть только один JedisPool, доступный для всех потоков без локальной копии, в соответствии с этим каждый Джедаи, используемые одним потоком, не будут доступны другому потоку.

redis.clients.jedis.exceptions.JedisConnectionException: не удалось получить ресурс из пула в redis.clients.util.Pool.getResource (Pool.java:22) в com.til.ibeat.service.JedisService.recursiveRedisConnection (JedisService. java: 60) в com.til.ibeat.service.JedisService.recursiveRedisConnection (JedisService.java:95) в com.til.ibeat.service.JedisService.recursiveRedisConnection (JedisService.java:95) в com.til.ibeat.service .JedisService.validateHitsCount (JedisService.java:52) в com.til.ibeat.controller.MashupController.handleRequest (MashupController.java:66) в org.springframework.web.servlet.mvc.SimpleControllerHandlerHandlerAdapter48 ) на org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:763) на org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:709) на orgletwork.survlet. processRequest (FrameworkServlet.java:613) на org.springframework.web.servlet.FrameworkServlet.doGet (FrameworkServlet.java:525) на javax.servlet.http.HttpServlet.service (HttpServlet.java:621) на javax.servlet.http.Hservice. : 728) на org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:305) на org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:210) на org.core.apache. StandardWrapperValve.invoke (StandardWrapperValve.java:222) в org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:123) в org.apache.catalina.authenticator.AuthenticatorBase.invoke47. или AuthenticatorBase.invoke47. .apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:171) в org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:99) в org.apache.catalina.valves.AccessLogValve (AccessLogValve .java: 936) на org.apache.catalina.core.StandardEngine. Valve.invoke (StandardEngineValve.java:118) на org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:407) на org.apache.coyote.http11.AbstractHttp11Processor.process (AbstractHttp11:Processor.process (AbstractHttp11:Processor.process) (AbstractHttp11.Processor.process) (AbstractHttp11:Processor.process) .apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process (AbstractProtocol.java:589) в org.apache.tomcat.util.net.JIoEndpoint $ SocketProcessor.run (JIoEndpoint.java:310) в $ java.util.concurrent.ThreadorPool .runTask (Неизвестный источник) в java.util.concurrent. ThreadPoolExecutor $ Worker.run (неизвестный источник) в java.lang.Thread.run (неизвестный источник) Причина: java.util.NoSuchElementException: не удалось создать проверенный объект, причина: сбой ValidateObject

person zenbeni    schedule 10.03.2014