본문 바로가기

IT 라이프

Tomcat DB Connection Pool 사용 시 누수 및 좀비세션 방지 방안

반응형

 Tomcat WAS 에서 Tomcat JDBC Connection Pool을 사용하고 있었는데, 이중화된 DB 중 한 대가 Down되어서 Fail-over가 되었으나 기존의 DB 커넥션 풀이 정리되지 않는 현상이 발생하였다. 이러한 문제를 해결하기 위해 방법을 알아보았다.

 

The Tomcat JDBC Connection Pool 와 Apache Commons DBCP의 차이 (tomcat-jdbc-pool vs commons-dbcp)

 먼저 WAS에서 어떤 타입의 커넥션풀을 사용하고 있는지에 대해 먼저 확인해보자. Tomcat에서 사용하는 커넥션풀은 크게 두 가지가 있는데 Tomcat JDBC Connection Pool(tomcat-jdbc-pool)이 더 개선된 방식이라고 보면 된다. server.xml 의 설정 내  Resource의 속성 중 factory 설정을 확인해보자. 이 설정이 'org.apache.tomcat.jdbc.pool.DataSourceFactory'로 되어 있는 경우 Tomcat JDBC Connection Pool을 사용하고 있는 것으로 판단하면 된다. 아닌 경우 Commons DBCP 를 사용하는 것으로 보면 되겠다.

 

  • Tomcat JDBC Connection Pool이 Apache Commons DBCP의 단점을 보완하고 기능을 추가한 개선된 방식임
  • Resource factory를 org.apache.tomcat.jdbc.pool.DataSourceFactory 를 사용할 경우 tomcat-jdbc-pool을 사용하는 것으로 판단 가능
  • org.apache.commons.dbcp.BasicDatasource를 사용할 경우 commons-dbcp를 사용하는 것으로 판단 가능
반응형

The Tomcat JDBC Connection Pool 의 설정 속성별 설명

 확인해보니 tomcat-jdbc-pool을 사용하고 있다면 아래 설정에 대해 자세히 확인해보자. 사실 commons-dbcp를 사용하는 경우더라도 결국 tomcat-jdbc-pool은 commons-dbcp를 참고하여 구현한 구현체이기 때문에 설정이 대부분 유사하여 어느정도 참고할 수 있을 것이다.

 

  • maxActive : 동시에 할당될 수 있는 최대 Active Connection 개수 (기본값 : 100)
  • maxIdle : 커넥션 풀에 반납할 때 최대로 유지될 수 있는 커넥션 개수 (기본값 : 8)
  • minIdle : 풀에 항시 최소한으로 유지되어야 하는 Established 커넥션 개수 (기본값 : 0)
  • timeBetweenEvictionRunsMillis (기본값 5000ms) :
    • Idle 커넥션 밸리데이션/클리너 스레드의 동작 간의 sleep time을 ms로 설정.
    • 이 값은 1초 이내로 설정되어서는 안된다.
    • 이 설정은 얼마나 자주 idle, abandoned 커넥션을 체크하고, 얼마나 자주 idle 커넥션의 유효성을 확인하는지를 결정한다.
    • 이 설정은 maxAge 설정이 0이 아니고 이 설정보다 낮을 경우 이 설정에 의해 덮어씌어진다.
  • removeAbandoned (기본값 false) :
    • removeAbandonedTimeout 에 설정된 값을 초과한 경우 유기된(Abandoned) 커넥션을 지울지 여부에 대한 설정.
    • 이 설정을 true로 할 경우 쿼리가 정상적으로 동작 중이어도 시간이 오래 걸리는 경우(removeAbandonedTimeout을 초과하는 경우) 커넥션을 삭제한다
    • ResetAbandonedTimer intercepter의 사용이 필수적일 것으로 추정됨.. 
  • removeAbandonedTimeout (기본값 60초) : 유기된(abandoned, in use) 커넥션이 삭제되기 전까지 기다리는 시간(초)을 설정
  • logAbandoned (기본값 false) : 유기된 커넥션을 삭제할 경우 로그를 남기는 설정. 물론 스택트레이스 생성에 대한 오버헤드가 발생함.
  • abandonWhenPercentageFull (기본값 0) :
    • 사용 중인 커넥션(in use)이 설정된 값을 상회하지 않으면, 타임아웃된 유기된 커넥션들이 종료되거나 리포트되지 않는다.
    • 값은 반드시 0에서 100 사이어야 한다.
    • 예를들어 기본값(0)으로 설정된 경우 removeAbandonedTimeout 에 도달한 경우 해당 커넥션은 즉시 삭제된다.
    • 50으로 설정된 경우, 풀 개수가 10이고 사용 중(in use)인 커넥션이 4개이면 해당 커넥션이 removeAbandonedTimeout을 초과해도 Abandon으로 인식될 뿐 커넥션이 종료되지는 않는다.

인터셉터 (Interceptors)

인터셉터 설정 방법

  • JDBC 인터셉터를 설정하는 방법은 jdbcInterceptors 프로퍼티를 활용하면 된다.
  • 여러개를 설정할 경우 세미콜론( ; )을 활용하면 된다.
  • 풀 클래스네임이 입력되지 않은 경우 앞에 org.apache.tomcat.jdbc.pool.interceptor. 의 prefix가 자동으로 붙는다.
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
 
jdbcInterceptors="ConnectionState;StatementFinalizer"
 
jdbcInterceptors="ConnectionState;StatementFinalizer(useEquals=true)"
 

ResetAbandonedTimer

  • full name : org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer

풀에서 커넥션을 가져올 때 Abandoned timer 가 시작한다. 이것은 30초의 타임아웃을 가지고 있다고 가정했을 때, 10초가 걸리는 쿼리를 10개 돌리면 해당 커넥션이 유기된(abandoned) 것으로 간주되고 abandonWhenPercentageFull 속성 설정에 따라 회수될 수 있음을 의미한다. 이 인터셉터를 사용하면 커넥션에서 무언가를 수행하거나 쿼리를 정상적으로 수행했을 때마다 타이머를 리셋한다.

 

jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"​

 

Apache commons DBCP인 경우의 DB Connection pool 누수 방지 방안

 The Apache Commons DBCP 2 를 사용하고 있는 경우라면 아래 설정을 해야 DB 커넥션이 삭제되고 재사용된다. 두 설정 모두 기본값은 false이다. removeAbandonedOnMaintenance 설정의 경우 timeBetweenEvictionRunsMillis 이 양수값으로 설정되어 있는 경우 아무런 영향을 주지 않는다.

  • removeAbandonedOnBorrow=true
  • removeAbandonedOnMaintenance=true

removeAbandonedTimeout 설정은 해당 커넥션이 버려진 것으로 간주하기 전에 몇 초동안 idle 상태로 둘 것인지에 대한 설정이다. 기본값은 300초(5분)이다.

  • removeAbandonedTimeout="60"

 

반응형