
HikariCP는 Spring Boot의 기본 커넥션 풀 라이브러리로, 낮은 지연 시간과 높은 처리량으로 널리 사용됩니다. 그러나 기본 설정만으로 운영 환경에 배포하면 커넥션 고갈, 응답 지연, 타임아웃 오류가 반복적으로 발생할 수 있습니다. 이 글에서는 HikariCP의 핵심 파라미터를 이해하고, 실제 프로젝트에 적용 가능한 커넥션 풀 최적화 전략을 다룹니다.
HikariCP 주요 설정 파라미터 이해
커넥션 풀 최적화의 첫 걸음은 각 파라미터가 무엇을 제어하는지 정확히 파악하는 것입니다. 잘못된 값 하나가 전체 서비스의 DB 연결을 차단할 수 있습니다.
| 파라미터 | 기본값 | 설명 |
|---|---|---|
maximumPoolSize |
10 | 풀에서 유지할 최대 커넥션 수 |
minimumIdle |
maximumPoolSize | 최소 유휴 커넥션 수 |
connectionTimeout |
30,000ms | 커넥션 획득 대기 최대 시간 |
idleTimeout |
600,000ms | 유휴 커넥션 유지 최대 시간 |
maxLifetime |
1,800,000ms | 커넥션 최대 수명 |
keepaliveTime |
0 (비활성) | DB 방화벽 타임아웃 방지용 ping 주기 |
maximumPoolSize를 무조건 높이는 것은 오히려 컨텍스트 스위칭 비용을 증가시킵니다. HikariCP 공식 문서는 pool size = (core_count * 2) + effective_spindle_count 공식을 권장하며, 일반적인 웹 애플리케이션에서는 10~20 범위가 적절합니다.
변경전 / 변경후 설정 비교
기본 설정을 그대로 사용하는 경우와 최적화된 설정을 비교합니다.
변경전 — Spring Boot 기본값에 의존하는 설정:
# application.yml (기본값 의존 — 문제 발생 가능)
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: user
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver이 상태에서는 maximumPoolSize=10, connectionTimeout=30s가 적용되며, 트래픽 급증 시 커넥션 대기 큐가 금방 포화됩니다.
변경후 — 운영 환경을 고려한 최적화 설정:
# application.yml (최적화 설정)
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?rewriteBatchedStatements=true&useSSL=false
username: user
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 20 # CPU(8코어) 기준: 8*2+4=20
minimum-idle: 5 # 유휴 커넥션 최소 유지 (빠른 응답)
connection-timeout: 5000 # 5초 초과 시 즉시 예외 (30초 대기 방지)
idle-timeout: 300000 # 5분 유휴 후 커넥션 회수
max-lifetime: 1200000 # 20분 — DB 방화벽 타임아웃보다 짧게 설정
keepalive-time: 60000 # 1분마다 ping으로 좀비 커넥션 방지
pool-name: MainHikariPool # 모니터링 시 풀 식별
connection-test-query: SELECT 1 # JDBC4 미지원 드라이버용 (MySQL 8+ 불필요)핵심 포인트:
max-lifetime은 반드시 DB 서버 또는 방화벽의wait_timeout보다 짧게 설정해야 합니다. MySQL의 기본wait_timeout은 28,800초(8시간)이지만, 클라우드 환경(AWS RDS, GCP Cloud SQL)에서는 더 짧게 설정된 경우가 많습니다.
Java Config로 다중 DataSource 관리
여러 DB를 사용하는 서비스에서는 application.yml보다 Java Config로 각 풀을 명시적으로 관리하는 것이 유지보수에 유리합니다.
@Configuration
public class DataSourceConfig {
// Primary DB — 트래픽 집중, 풀 크기 크게
@Bean
@Primary
public DataSource primaryDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://primary-db:3306/main");
config.setUsername("user");
config.setPassword("secret");
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.setConnectionTimeout(5_000); // 5초
config.setMaxLifetime(1_200_000); // 20분
config.setKeepaliveTime(60_000); // 1분
config.setPoolName("PrimaryPool");
return new HikariDataSource(config);
}
// Read Replica — 읽기 전용, 풀 크기 중간
@Bean
public DataSource readReplicaDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://replica-db:3306/main");
config.setUsername("reader");
config.setPassword("secret");
config.setMaximumPoolSize(10);
config.setMinimumIdle(3);
config.setConnectionTimeout(3_000);
config.setMaxLifetime(1_200_000);
config.setReadOnly(true); // 읽기 전용 명시
config.setPoolName("ReplicaPool");
return new HikariDataSource(config);
}
}HikariCP 모니터링 — 풀 상태 실시간 확인
설정 후에는 실제 풀이 예상대로 동작하는지 모니터링해야 합니다. Spring Boot Actuator와 Micrometer를 조합하면 Prometheus + Grafana 대시보드에서 커넥션 풀 지표를 실시간으로 확인할 수 있습니다.
build.gradle에 의존성을 추가합니다:
// build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'
}application.yml에서 메트릭 노출을 활성화합니다:
management:
endpoints:
web:
exposure:
include: health, metrics, prometheus
metrics:
tags:
application: ${spring.application.name}이후 /actuator/metrics/hikaricp.connections.active 엔드포인트에서 아래와 같은 응답을 확인할 수 있습니다:
{
"name": "hikaricp.connections.active",
"measurements": [
{ "statistic": "VALUE", "value": 4.0 }
],
"availableTags": [
{ "tag": "pool", "values": ["MainHikariPool"] }
]
}주목해야 할 주요 메트릭은 다음과 같습니다:
hikaricp.connections.active: 현재 사용 중인 커넥션 수hikaricp.connections.pending: 커넥션 대기 중인 스레드 수 — 이 값이 지속적으로 0 이상이면 풀 부족 신호hikaricp.connections.timeout: 타임아웃 발생 횟수 — 증가 추세라면connectionTimeout또는maximumPoolSize조정 필요
맺음말
HikariCP 커넥션 풀 최적화는 단순히 maximumPoolSize를 늘리는 작업이 아닙니다. 서버 코어 수, DB 서버 스펙, 방화벽 타임아웃, 애플리케이션 쿼리 패턴을 종합적으로 고려해야 적절한 값을 도출할 수 있습니다.
핵심 원칙을 정리하면 다음과 같습니다:
max-lifetime은 반드시 DBwait_timeout보다 짧게 설정connectionTimeout은 30초가 아닌 3~5초로 줄여 빠른 장애 감지 유도keepaliveTime으로 클라우드 환경의 좀비 커넥션 사전 차단- Micrometer 메트릭으로
pending커넥션을 지속 모니터링
커넥션 풀 설정은 초기에 맞춰 놓고 잊어버리는 것이 아니라, 트래픽 패턴 변화에 따라 주기적으로 재검토해야 합니다. HikariCP 공식 문서의 "About Pool Sizing" 섹션도 함께 참고하면 이론적 배경을 더 깊이 이해하는 데 도움이 됩니다.
'프로그래밍 PROGRAMMING > 자바 JAVA AND FRAMEWORKS' 카테고리의 다른 글
| Spring Authorization Server로 OAuth2 인증 서버 구축하기 (0) | 2026.03.20 |
|---|---|
| GraalVM Native Image로 Spring Boot 시작 시간 줄이기 (0) | 2026.03.16 |
| OpenTelemetry로 분산 트레이싱 구축하기: Spring Boot 적용 가이드 (1) | 2026.03.12 |
| [JAVA] JVM GC 튜닝으로 자연시간 줄이기 (0) | 2026.03.09 |
| Spring Boot 테스트 전략: @SpringBootTest vs 슬라이스 테스트 선택 (0) | 2026.03.09 |