✅ Connection Pool이란?
Connection Pool은 데이터베이스 연결을 미리 생성해 두고, 요청이 들어올 때마다 미리 생성해 둔 연결을 제공하는 기술이다.
데이터베이스 연결은 생성하는 데 시간이 오래 걸리기 때문에, 매 요청마다 연결을 생성하면 성능이 저하된다.
Connection Pool은 이러한 문제를 해결하기 위해 연결을 미리 생성해 두고 재사용함으로써 성능을 향상시킨다.
✅ Java JDBC와 HikariCP
Java 애플리케이션에서 가장 널리 사용되는 커넥션 풀 중 하나는 HikariCP 이다. HikariCP는 가볍고 빠른 커넥션 풀로, 대규모 트래픽이 발생하는 상황에서도 효율적인 연결 관리를 지원한다. HikariCP는 HikariPoolMXBean과 HikariConfigMXBean이라는 JMX(Java Management Extensions)를 통해 커넥션 풀의 상태 및 설정을 관리할 수 있다.
📌 Spring Boot에서의 HikariCP 설정과 기본값
Spring Boot에서는 spring.datasource.hikari
프로퍼티를 통해 HikariCP의 설정을 지정할 수 있다. HikariCP의 기본 설정은 다음과 같다.
설정항목 | 설명 | 기본값 |
---|---|---|
maximumPoolSize | 최대 커넥션 풀 크기 (이 수치를 초과한 요청은 대기 상태로 들어감) | 10 |
minimumIdle | 최소 유휴 커넥션 수 (유휴 커넥션이 이 수치 이하로 떨어지면 새로운 커넥션 생성) (보통 최적화를 위해 설정하기 않거나 maximumPoolSize와 똑같이 맞추는걸 추천) | 10 |
connectionTimeout | 커넥션 타임아웃 시간 (커넥션을 가져오기 위해 스레드가 대기하는 최대 시간) | 30s |
idleTimeout | 유휴 커넥션 타임아웃 시간 (커넥션 풀에서 유지될 수 있는 시간) | 10m |
maxLifetime | 커넥션 최대 생존 시간 (시간이 지나면 폐기 후 새 커넥션 생성) | 30m |
poolName | 커넥션 풀 이름 | HikariPool-1 |
connectionTestQuery | 커넥션 테스트 쿼리 | null |
validationTimeout | 커넥션 유효성 검사 타임아웃 | 5s |
leakDetectionThreshold | 커넥션 누수 검사 임계값 | 0 |
registerMbeans | JMX 빈 등록 여부 | false |
initializationFailTimeout | 커넥션 풀 초기화 실패 타임아웃 | 1s |
isolateInternalQueries | 내부 쿼리 분리 여부 | false |
allowPoolSuspension | 커넥션 풀 일시 중지 허용 여부 | false |
readOnly | 읽기 전용 여부 | false |
connectionTestQuery | 커넥션 테스트 쿼리 | null |
keepaliveTime | 커넥션 풀 유지 시간 (DB 가 커넥션을 자체적으로 끊지 않도록 HikariCP가 DB 헬스체크 Connection.isValid() 를 호출해주는 최대) | 10m |
📌 HikariCP 설정 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
hikari:
maximum-pool-size: 10 # 최대 커넥션 풀 크기
minimum-idle: 5 # 최소 유휴 커넥션 수
connection-timeout: 30000 # 커넥션 타임아웃 시간
idle-timeout: 600000 # 유휴 커넥션 타임아웃 시간
max-lifetime: 1800000 # 커넥션 최대 생존 시간
pool-name: test-pool # 커넥션 풀 이름
connection-test-query: SELECT 1 # 커넥션 테스트 쿼리
validation-timeout: 5000 # 커넥션 유효성 검사 타임아웃
leak-detection-threshold: 0 # 커넥션 누수 검사 임계값
register-mbeans: false # JMX 빈 등록 여부
initialization-fail-timeout: 1000 # 커넥션 풀 초기화 실패 타임아웃
isolate-internal-queries: false # 내부 쿼리 분리 여부
allow-pool-suspension: false # 커넥션 풀 일시 중지 허용 여부
read-only: false # 읽기 전용 여부
📌 HikariCP 설정 주의사항
maximumPoolSize
와minimumIdle
은 서로 비슷한 값으로 설정하는 것이 좋다.connectionTimeout
,idleTimeout
,maxLifetime
등의 시간 설정은 DB와의 네트워크 지연을 고려하여 적절히 설정해야 한다.connectionTestQuery
는 커넥션 풀이 유효한지 확인하는 쿼리로, DB에 따라 적절한 쿼리를 설정해야 한다.leakDetectionThreshold
는 커넥션 누수 검사 임계값으로, 0으로 설정하면 누수 검사가 비활성화된다.registerMbeans
는 JMX 빈 등록 여부로, 모니터링을 위해 설정한다.isolateInternalQueries
는 내부 쿼리 분리 여부로,true
로 설정하면 내부 쿼리가 외부 쿼리와 분리된다.allowPoolSuspension
은 커넥션 풀 일시 중지 허용 여부로,true
로 설정하면 커넥션 풀을 일시 중지할 수 있다.readOnly
는 읽기 전용 여부로,true
로 설정하면 읽기 전용 트랜잭션을 사용할 수 있다.keepaliveTime
은 커넥션 풀 유지 시간으로, DB가 커넥션을 자체적으로 끊지 않도록 HikariCP가 DB 헬스체크Connection.isValid()
를 호출해주는 최대 시간이다.initializationFailTimeout
은 커넥션 풀 초기화 실패 타임아웃으로, 커넥션 풀 초기화에 실패할 경우 대기 시간을 설정한다.validationTimeout
은 커넥션 유효성 검사 타임아웃으로, 커넥션 유효성 검사에 대한 타임아웃을 설정한다.
📌 Connection Pool 과 스레드의 상관관계 ( HikariCP 데드락 )
connection pool size의 경우 서버의 최대 스레드 수를 적절하게 지정해주어야 한다.
아니면 Pool Locking 으로 HikariCP 자체 데드락이 발생할 수 있다.
다행히도 이는 잘 알려진 이슈라서 아래 링크를 참고하여 공식에 따라 개수를 지정해주면 안전하다.
(2020 배달의민족) HikariCP Dead lock에서 벗어나기 (이론편)
📌 트러블슈팅 가이드
HikariCP를 사용하는 중 자주 발생하는 문제와 그 해결 방법을 아래와 같이 정리하였다.
Connection is not available
예외: 최대 풀 크기에 도달하여 더 이상 커넥션을 제공할 수 없는 경우 발생. 이때는 maximumPoolSize
를 늘리거나 애플리케이션의 커넥션 사용 방식을 최적화해야 한다.
Connection leak detected
예외: 커넥션이 반납되지 않는 경우 발생. leakDetectionThreshold
를 설정해 누수 발생 시 로그로 기록하도록 하여 원인을 파악할 수 있다.
참고 자료