본문 바로가기
IT/java by 하루 또다시 하루 2026. 6. 4.
반응형

HikariCP 핵심 설정 완벽 정리: maxLifetime, idleTimeout, connectionTimeout의 차이

Spring Boot 환경에서 데이터베이스를 연동할 때 대부분 HikariCP를 기본 커넥션 풀(Connection Pool)로 사용합니다. 하지만 설정을 튜닝할 때 maxLifetime, idleTimeout, connectionTimeout 값을 혼동하는 경우가 매우 많습니다.

이 세 가지 설정은 모두 밀리초(ms) 단위의 시간 설정이라는 공통점이 있지만, 그 역할과 동작 방식은 완전히 다릅니다. 이 차이를 정확히 이해하지 못하면 커넥션이 갑자기 고갈되거나 잦은 DB 연결 오류가 발생할 때 엉뚱한 설정만 건드리게 됩니다.

결론부터 말씀드리면 maxLifetime은 커넥션의 최대 수명, idleTimeout은 유휴 커넥션의 정리 기준 시간, connectionTimeout은 커넥션을 빌리기 위한 대기 시간입니다. 이 글에서는 각 설정의 차이점과 올바른 튜닝 방법을 정리합니다.

자주 발생하는 HikariCP 연결 문제 증상

커넥션 풀 설정이 잘못되었을 때 애플리케이션에서는 다음과 같은 증상들이 나타납니다.

  • 간헐적인 DB 연결 실패 및 타임아웃 발생
  • 커넥션 풀의 크기가 예상과 다르게 비정상적으로 줄어든 것처럼 보임
  • 특정 스케줄러나 배치 작업 실행 중 DB 응답이 심하게 지연됨
  • 로그에 Connection is not available, request timed out after... 오류 출력
  • 데이터베이스 측에서 커넥션이 너무 자주 생성되고 닫히는 현상(Connection Churn) 관찰

이러한 문제들은 대부분 애플리케이션 코드의 결함이 아니라, 커넥션 풀 설정이 DB 환경과 맞지 않아 발생합니다.

왜 이런 문제가 발생할까?

1) 시간 설정의 역할을 혼동하는 경우

세 가지 설정 모두 시간과 관련된 값이다 보니, "이 값을 늘리면 연결이 안 끊기겠지?"라는 생각으로 임의로 값을 조정하는 경우가 많습니다. 특히 maxLifetime을 너무 짧게 잡으면 멀쩡한 커넥션을 계속 버리고 새로 맺어야 하므로 엄청난 성능 저하(오버헤드)를 유발합니다.

2) DB 서버 및 인프라의 타임아웃과 맞지 않는 경우

HikariCP의 설정은 애플리케이션 단독으로 결정할 문제가 아닙니다. 데이터베이스 서버 자체의 타임아웃(예: MySQL의 wait_timeout)이나 중간에 위치한 네트워크 장비(L4, L7, 방화벽 등)가 커넥션을 먼저 끊어버리는 경우가 있습니다. 이때 HikariCP가 이미 끊어진 커넥션을 재사용하려고 시도하면 치명적인 오류가 발생합니다.

3대 타임아웃 설정 핵심 비교

세 가지 설정의 역할을 한눈에 파악할 수 있도록 표로 정리했습니다.

설정명 역할 설명
maxLifetime 커넥션 최대 생존 시간 풀에 생성된 커넥션이 유지될 수 있는 절대적인 최대 수명
idleTimeout 유휴 커넥션 대기 시간 사용되지 않고 놀고 있는 커넥션을 풀에서 제거하기까지의 시간
connectionTimeout 커넥션 획득 대기 시간 애플리케이션이 풀에서 커넥션을 빌릴 때 기다리는 최대 시간

단계별 확인 및 튜닝 가이드

1단계. maxLifetime (가장 중요한 설정)

풀 안의 커넥션 하나가 살아있을 수 있는 최대 시간입니다.

Properties
 
spring.datasource.hikari.max-lifetime=1800000

이 값이 도달하면 해당 커넥션은 사용 중이더라도 작업이 끝난 직후 풀에서 제거(Close)됩니다.

  • 주의할 점: 인프라 네트워크나 DB 서버의 커넥션 타임아웃 설정보다 반드시 2~3초 이상 짧게 설정해야 합니다. DB 서버가 먼저 커넥션을 끊어버렸는데 HikariCP가 이를 모른 채 애플리케이션에 할당하면 통신 오류가 발생하기 때문입니다. 반대로 너무 짧게(예: 1분 이하) 잡으면 커넥션 생성/제거 비용이 너무 커집니다.

2단계. idleTimeout

커넥션이 사용되지 않고 풀에서 대기(Idle)하는 상태를 얼마나 허용할지 결정합니다.

Properties
 
spring.datasource.hikari.idle-timeout=600000
  • 주의할 점: 이 설정은 minimumIdle 값이 maximumPoolSize보다 작을 때만 의미가 있습니다. 만약 두 값을 동일하게 맞추어 고정 크기 풀(Fixed Pool)로 운영한다면, idleTimeout 설정은 무시되고 커넥션이 회수되지 않습니다. (HikariCP 제작자는 고정 크기 풀 운영을 권장합니다.)

3단계. connectionTimeout

애플리케이션(스레드)이 DB 작업을 위해 풀에서 커넥션을 빌려올 때 기다려주는 최대 시간입니다.

Properties
 
spring.datasource.hikari.connection-timeout=30000

이 시간이 지나도록 커넥션을 얻지 못하면 악명 높은 Connection is not available 에러가 발생합니다.

  • 주의할 점: 이 에러가 난다고 무작정 connectionTimeout 시간을 늘리는 것은 위험합니다. 대기 시간이 길어지면 사용자의 요청 스레드도 같이 멈춰버리기 때문입니다. 설정값을 늘리기 전에 왜 커넥션을 오랫동안 반납하지 못하고 있는지(느린 쿼리, 긴 트랜잭션 등)를 먼저 찾아야 합니다.

4단계. maximumPoolSize와의 연관성 분석

시간 설정만 본다고 문제가 해결되지 않습니다. 풀의 전체 크기를 결정하는 maximumPoolSize와 반드시 연계해서 분석해야 합니다.

Properties
 
spring.datasource.hikari.maximum-pool-size=10
  • 커넥션 획득 대기가 많고 타임아웃이 발생한다면: maximumPoolSize가 너무 작거나, 쿼리 처리 시간이 긴 것입니다.
  • 커넥션이 너무 자주 교체된다면: maxLifetime이 너무 짧게 설정된 것입니다.
  • 사용량에 비해 DB 메모리 점유가 높다면: 고정 풀 크기가 불필요하게 크게 잡혀있는지 검토해야 합니다.

실전에서 자주 놓치는 부분

오류가 나면 무조건 maximumPoolSize부터 늘리는 실수

Connection is not available 오류가 발생했을 때 가장 흔히 하는 실수가 풀 사이즈를 10에서 50, 100으로 대폭 늘리는 것입니다. 하지만 특정 쿼리에 병목이 있거나 외부 API 응답을 기다리느라 트랜잭션을 쥐고 있는 상태라면, 풀 사이즈를 아무리 늘려도 결국 모두 고갈되고 DB 서버의 부하만 가중시킵니다. 근본적인 원인인 '느린 트랜잭션'을 잡아야 합니다.

HikariCP 디버그 로그의 활용 부재

설정값을 변경하기 전후로 반드시 HikariCP의 디버그 로그를 활성화하여 커넥션의 상태(Total, Active, Idle, Waiting) 변화를 관찰해야 합니다. 로그를 보지 않고 설정값만 바꾸는 것은 눈을 감고 운전하는 것과 같습니다.

마무리

HikariCP의 maxLifetime, idleTimeout, connectionTimeout은 이름은 비슷하지만 적용되는 대상과 시점이 명확히 다릅니다.

DB 연결 문제가 발생했다면 단순히 이 세 가지 값을 늘리거나 줄이는 데 집중하지 말고, maximumPoolSize와 실제 쿼리 실행 시간, 그리고 인프라단의 타임아웃 설정을 종합적으로 점검하시기 바랍니다. 각 설정의 정확한 역할을 이해하고 접근하면 어떤 연결 문제든 빠르고 정확하게 원인을 규명할 수 있습니다.

반응형