◇ PART · DB

HikariCP 커넥션 풀

왜 풀(Pool)이 필요한가

학습 목표

  • 커넥션 풀 이 무엇인지 안다
  • 풀이 없을 때의 성능 문제를 이해
  • HikariCP 의 주요 설정을 안다

⚠️ 매번 새 연결을 만들면

DB 연결 생성 비용

getConnection()」 한 번에 일어나는 일:

  1. TCP 소켓 연결 (3-way handshake)
  2. 인증 (사용자명·비밀번호)
  3. 세션 초기화 (인코딩·시간대 등)
  4. 총 약 50~100ms

매 요청마다 이 과정 → 응답 시간이 0.1초 → 1초로. 동시 사용자 100 명이면 — 시스템 마비.

🛠️ 커넥션 풀 — 미리 깎아둔 칼통

미리 만들어둔 연결의 묶음

주방에서 「칼을 매번 깎지 말고 미리 칼통에 모아두자」 의 발상. DB 연결도 미리 N 개 만들어두고 — 필요할 때 꺼내 쓰고 반납.

주방 칼통
풀 없음 요청 → [연결 생성 50ms] → 쿼리 → [연결 종료 30ms] 풀 있음 요청 → [풀에서 연결 꺼냄 1ms] → 쿼리 → [풀에 반납 1ms] (연결 자체는 재사용)

HikariCP — 가장 빠른 자바 풀

HikariCP = 가장 빠른 자바 커넥션 풀로 알려진 라이브러리. Spring Boot 의 기본 풀.

  • 경량 (작은 jar)
  • 빠름 (벤치마크 1 위)
  • 안정성 — 예외 처리 견고
  • 설정 간단

설정 — root-context.xml


<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
    <property name="jdbcUrl"
        value="jdbc:mysql://localhost:3306/spring_db?characterEncoding=UTF-8&serverTimezone=UTC" />
    <property name="username" value="root" />
    <property name="password" value="1234" />
    <property name="maximumPoolSize" value="10" />
    <property name="connectionTimeout" value="30000" />
    <property name="idleTimeout" value="600000" />
</bean>

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
      destroy-method="close">
    <constructor-arg ref="hikariConfig" />
</bean>

주요 설정 옵션

옵션의미기본/권장
maximumPoolSize최대 연결 수10
minimumIdle최소 유휴 연결 수10 (max 와 같게 권장)
connectionTimeout연결 대기 시간30000 (30초)
idleTimeout유휴 연결 유지 시간600000 (10분)
maxLifetime연결의 최대 수명1800000 (30분)

maximumPoolSize 어떻게 정하나

너무 작으면 — 요청이 풀 대기 큐에서 기다림.
너무 크면 — DB 가 부담.

실무 공식 (HikariCP 권장): (코어 수 × 2) + 1 정도부터 시작.

  • 4 코어 서버 → 9 ~ 10
  • 학습 환경 → 10 으로 충분
  • 실제 서비스 → 부하 테스트 후 조정

풀의 동작

서버 시작 ↓ 풀 초기화 — 연결 10 개 미리 만듦 ↓ ┌──────────────────┐ │ 풀 (10 개 연결) │ │ 연결1 (idle) │ │ 연결2 (idle) │ │ 연결3 (idle) │ │ ... │ └──────────────────┘ ↓ 요청 도착 ↓ conn = ds.getConnection() ⇒ 풀에서 idle 연결 1 개를 active 로 표시해서 반환 (1ms) ↓ 쿼리 실행 ↓ conn.close() ⇒ 실제 닫지 않고 풀에 반납 (active → idle)

풀 고갈 (Pool Exhausted)

풀이 부족할 때

동시 요청 > maximumPoolSize 면 — 추가 요청은 connectionTimeout 만큼 기다림. 그래도 못 받으면 예외.


SQLTransientConnectionException: Connection is not available

원인:

  • 풀 사이즈 너무 작음 — 늘리기
  • 연결 안 닫힌 채 누수 (leak) — 코드 점검
  • 긴 쿼리 — 인덱스 추가 등 SQL 최적화

모니터링 — 누수 감지


<property name="leakDetectionThreshold" value="60000" />
<!-- 60 초 이상 연결을 잡고 있으면 경고 로그 -->

👉 개발 단계에서 켜두면 — 「연결을 닫지 않은 코드」 를 잡아낼 수 있음.

다른 풀과 비교

특징
HikariCP빠름. 본 과정 + Spring Boot 기본 ⭐
Apache Commons DBCP전통적. 기능 많음
C3P0옛날 기본. 지금은 거의 안 씀
Tomcat JDBC PoolTomcat 내장

🔄 Before / After

전 차시 끝

DataSource 가 무엇인지 막연.

이번 차시 끝

커넥션 풀의 의미와 효과를 안다. HikariCP 의 주요 옵션을 안다.

정리

오늘 들고 가는 것

  • 커넥션 풀 = 미리 만들어둔 연결의 묶음
  • 매 요청마다 새 연결 X — 풀에서 꺼내 쓰고 반납
  • HikariCP = 가장 빠른 자바 풀. Spring Boot 기본
  • maximumPoolSize 10 으로 시작 → 부하에 따라 조정