2014-02-27 5 views
0

안녕 모두 나는 자바를 사용하여 redis 서버를 설정하려고합니다. Redis 서버는 ulimit가 무제한 인 Linux 서버입니다. 여기 풀에서 리소스를 가져올 수 없습니다. JedisConnectionException

연결을 만들어 내 봄 콩입니다

공용 클래스 JedisService이 IJedisService, InitializingBean 표시, DisposableBean 표시를 구현 { 개인 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는 제어기에 호출된다. 내가 여러 스레드에서이 코드를 실행하면 는하지만 난이 오류를

redis.clients.jedis.exceptions.JedisConnectionException를 얻을 : (redis.clients.util.Pool.getResource에서 풀 에서 풀 리소스를 가져올 수 없습니다. java : 22) at com.til.ibeat.service.JedisService.recursiveRedisConnection (JedisService.java:60) at com.til.ibeat.service.JedisService.recursiveRedisConnection (JedisService.java:95) at com.til. ibeat.service.JedisService.recursiveRedisConnection (JedisService.java:95) com.til.ibeat.service.JedisService.validateHitsCount (JedisService.java:52) at com.til.ibeat.controller.MashupController.handleRequest (MashupController. java : 66)(SimpleControllerHandlerAdapter.java:48) at org.springframework.web.servlet.mvc.SD org.springframework.web.servlet.FrameworkServlet.doGet (FrameworkServlet.java : 0) 525) (javax.servlet.http.HttpServlet.java:621) internalDoFilter (ApplicationFilterChain.java:305) at org.apache. org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.)에서 을 가져 오십시오. java : 123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:171) at org.apache. catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke (AccessLogValve.java:936) at org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve. java : 118) at org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.j ava : 407) at org.apache.coyote.http11.AbstractHttp11Processor.process (AbstractHttp11Processor.java:1004) at org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process (AbstractProtocol.java:589) at org.apache. tomcat.util.net.JIoEndpoint $ SocketProcessor.run (JIoEndpoint.java:310) at java.util.concurrent.ThreadPoolExecutor $ Worker.runTask (알 수없는 소스) at java.util.concurrent.ThreadPoolExecutor $ Worker.run (알 수 없음) 소스) at java.lang.Thread.run (알 수없는 소스) 발생 원인 : java.util.NoSuchElementException : 유효성이 검사 된 개체를 만들 수 없습니다. 원인 : ValidateObject가 실패했습니다.

답변

1

JedisPool이 인스턴스화 된 것을 확인 했습니까?

스프링 빈이 많은 스레드를 통해 액세스되고 Jedis가 스레드로부터 안전하지 않기 때문에 이상한 Jedis 인스턴스를 반환하는 둘 이상의 JedisPool 또는 다른 스레드에서 동시에 사용하는 jedis 인스턴스를 가질 수 있습니다. 각 스레드는이 JedisPool 및/또는 Jedis 인스턴스의 로컬 복사본을 가질 수 있으며 그로부터 오류가 발생합니다.

두 가지 옵션이 있습니다. JedisPool을 정적 최종 (클래스 로더 당 하나의 값만)으로 선언하거나 이중 체크 잠금 (휘발성과 함께)을 사용하여 로컬 스레드없이 모든 스레드가 액세스하는 JedisPool이 하나만 있는지, 스레드에 의해 사용 된 각 Jedis는 다른 스레드에 의해 액세스되지 않는다고합니다.

관련 문제