Connection Pool 설정 가이드 - HikariCP


HikariCP는 가장 빠른 Java JDBC Connection Pool입니다. Spring Boot의 기본 Connection Pool로, 적절한 설정이 애플리케이션 성능과 안정성에 큰 영향을 미칩니다.



언제 중요한가요?



  • 동시 사용자가 많은 웹 애플리케이션

  • DB 연결 오류가 발생할 때

  • 응답 시간이 느려질 때

  • Connection Timeout 에러 발생 시



기본 설정 (application.yml)


spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver

hikari:
# 풀 사이즈
maximum-pool-size: 10
minimum-idle: 5

# 타임아웃
connection-timeout: 30000 # 30초
idle-timeout: 600000 # 10분
max-lifetime: 1800000 # 30분

# 연결 테스트
connection-test-query: SELECT 1

# 풀 이름 (모니터링용)
pool-name: MyHikariPool


핵심 파라미터 설명


maximum-pool-size (기본: 10)
- 풀에서 유지할 최대 커넥션 수
- 공식: connections = (core_count * 2) + effective_spindle_count
- 보통 10-20 정도로 시작

minimum-idle (기본: maximum-pool-size)
- 유휴 상태로 유지할 최소 커넥션 수
- maximum-pool-size와 같게 설정 권장 (고정 크기)

connection-timeout (기본: 30000ms)
- 풀에서 커넥션 얻기까지 대기 시간
- 너무 짧으면 에러 빈발, 너무 길면 응답 지연

idle-timeout (기본: 600000ms = 10분)
- 유휴 커넥션 유지 시간
- minimum-idle보다 많은 커넥션만 해당

max-lifetime (기본: 1800000ms = 30분)
- 커넥션 최대 수명
- DB의 wait_timeout보다 짧게 설정
- MySQL 기본 wait_timeout: 8시간


환경별 권장 설정


# 소규모 (동시 사용자 100명 이하)
hikari:
maximum-pool-size: 5
minimum-idle: 2
connection-timeout: 30000

# 중규모 (동시 사용자 1000명 이하)
hikari:
maximum-pool-size: 15
minimum-idle: 10
connection-timeout: 20000

# 대규모 (동시 사용자 1000명 이상)
hikari:
maximum-pool-size: 30
minimum-idle: 20
connection-timeout: 10000

# 읽기/쓰기 분리 시 각 DataSource별 설정


Java Config 설정


@Configuration
public class DataSourceConfig {

@Bean
@ConfigurationProperties("spring.datasource.hikari")
public HikariConfig hikariConfig() {
return new HikariConfig();
}

@Bean
public DataSource dataSource(HikariConfig config) {
config.setMaximumPoolSize(10);
config.setMinimumIdle(5);
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
config.setPoolName("MyHikariPool");

// 연결 유효성 검사
config.setConnectionTestQuery("SELECT 1");

// 누수 감지 (개발 환경)
config.setLeakDetectionThreshold(60000); // 60초

return new HikariDataSource(config);
}
}


연결 누수 감지


hikari:
leak-detection-threshold: 60000 # 60초

# 60초 이상 반환되지 않은 커넥션 로그 출력
# 개발/테스트 환경에서 활성화
# 운영 환경에서는 0 (비활성화)

# 누수 로그 예시
# Connection leak detection triggered for connection,
# stack trace follows


모니터링


// Actuator + Micrometer
management:
endpoints:
web:
exposure:
include: health,metrics
metrics:
export:
prometheus:
enabled: true

// 주요 메트릭
hikaricp.connections.active # 사용 중인 커넥션
hikaricp.connections.idle # 유휴 커넥션
hikaricp.connections.pending # 대기 중인 요청
hikaricp.connections.timeout # 타임아웃 발생 수
hikaricp.connections.max # 최대 풀 크기

// JMX로 모니터링
HikariPoolMXBean poolMXBean = ...;
poolMXBean.getActiveConnections();
poolMXBean.getIdleConnections();
poolMXBean.getTotalConnections();


문제 해결


1. Connection Timeout 에러
- maximum-pool-size 증가
- 쿼리 실행 시간 확인
- 트랜잭션 범위 축소

2. Connection is not available
- 커넥션 누수 확인
- leak-detection-threshold 활성화
- @Transactional 범위 확인

3. Connection reset by peer
- max-lifetime을 DB timeout보다 짧게
- connection-test-query 확인
- 네트워크/방화벽 설정 확인

4. 메모리 부족
- maximum-pool-size 감소
- 각 커넥션 메모리: 약 1MB


MySQL 연동 시 추가 설정


spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?
useSSL=false&
allowPublicKeyRetrieval=true&
serverTimezone=Asia/Seoul&
characterEncoding=UTF-8&
autoReconnect=true&
cachePrepStmts=true&
prepStmtCacheSize=250&
prepStmtCacheSqlLimit=2048


공식 추천



  • Pool Size = (core_count * 2) + disk_spindle_count

  • 10-20개로 시작하여 모니터링 후 조정

  • 너무 크게 설정하면 오히려 성능 저하

  • fixed pool (minimum = maximum) 권장