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"
'IT 라이프' 카테고리의 다른 글
Apache Tomcat Connectors 중 Status Worker에 관하여 (JK Status Manager) (0) | 2023.08.11 |
---|---|
JBoss EAP의 Datasource (DB Pool) 모니터링 및 최소값 설정 방법 (0) | 2023.08.11 |
공인 쿠버네티스 자격증 알아보기 (CKA, CKAD, CKS, KCNA) (1) | 2022.04.04 |
MySQL 마이너 버전 업그레이드 방법 (5.7버전, 수작업 기준) (0) | 2022.03.07 |
[Visual SVN] pre-commit hook 샘플 - 커밋 메세지 또는 이슈번호 입력 체크, 삭제 금지 등 (0) | 2021.08.24 |