반응형
Connection Pooling이 없을 때의 DB 연결 방법
1. TCP 연결
- 애플리케이션이 “DB 서버야, 연결해줘” 하고 요청
- DB 서버가 “좋다” 하고 응답
- 네트워크에서 SYN → SYN/ACK → ACK 왕복
2. TLS/SSL 핸드셰이크
- 암호화 연결을 쓸 경우 서로 열쇠 교환해서 보안 통로 확보
3. 인증
- 클라이언트가 아이디/비밀번호를 보냄
- DB서버는 “비번, 권한 전부 체크 후 들어와”하고 허락
4. 세션 초기화
- DB 서버가 새로운 “세션(대화방)”을 만들어줌
- 기본 설정들을 관리
- 사용할 DB
- 문자셋/ 시간대
- autocommit 모드, isolation level 등
5. 준비 완료
- 첫 쿼리를 실행할 수 있음
6. 커넥션 닫기
- Connection.close() 호출 → TCP 연결도 종료
- 서버는 “이 세션 끝!” 하고 정리
- 네트워크 리소스(TIME_WAIT)도 소모
이 과정의 비용이 비쌈
- 위 과정이 요청마다 반복되면 네트워크 왕복 + 인증 + 세션 생성 비용이 매번 듦
- 빠른 로컬 DB라도 수 ms~수십 ms는 기본, TLS 켜면 더 커짐
- 요청이 몰리면 성능 병목 발생
이렇기에 커넥션 풀 등장
- 앱 시작 시 미리 여러 개 커넥션을 열어둠 (위 1~4번을 선행)
- 요청이 오면 → 바로 빌려줌(0.x ms 수준)
- 사용 후 close() 해도 실제론 닫지 않고 풀에 반환해서 재사용
쉽게 말하면,
- 풀 없이: 손님 올 때마다 테이블/의자 새로 사옴 → 비싸고 느림
- 풀 쓰면: 미리 테이블/의자 준비해둠 → 손님 오면 바로 안내, 쓰고 나가면 다음 손님 재사용
Connection Pooling 개념 및 동작 방식
DB 연결을 미리 여러 개 만들어주고, 요청이 오면 빌려주고 끝나면 다시 돌려받아 재사용하는 창고
동작 방식
1. 웜업 == DB 접속
- 앱이 뜰 때 또는 트래픽에 맞춰 초기 커넥션을 여러 개 만들어 둠
- (Hikrai : minimun-idle 개수 만큼 유휴 연결 유지)
2. 빌리기 - getConnection() == DB 접속
- 요청 들어옴 → 풀에 놀고 있는 커넥션이 있으면 즉시 반환
- 없으면
- 아직 maximum-pool-size 미만이면 새 연결 생성
- 이미 꽉 찼으면 대기 (최대 connection-timeout까지만)
- 시간 내 못 빌리면 시간초과 예외(풀 고갈)
3. 사용(In-use) == 트랜잭션 시작, SQL 실행, 트랜잭션 종료
- 스프링 트랜잭션이 시작되면 풀에서 빌린 커넥션에 옵션을 세팅
- autoCommit=false, readOnly, isoaltion 등
- JPA/Hibernate가 이 커넥션으로 SQL 실행
- 트랜잭션 종료 시 커밋/롤백
4. 반납(Return) - Close() == 트랜잭션 닫기
- 애플리케이션에서 close()를 호출해도 실제로 소켓을 닫지 않고 커넥션을 풀에 되돌림(상태 초기화 후 유휴 상태로)
- Hikrai가 세션 상태를 리셋해서 다음 요청이 깨끗한 환경으로 쓰게 함
5. 유지/교체(Maintain) == 트랜잭션 닫기
- 너무 오래된 커넥션은 교체(max-lifetime)
- 오랫동안 안 쓰인 유휴 연결은 정리(idle-timeout)
- 연결이 죽었는지 헬스 체크(JDBD isValid()/keepalive)
튜닝 포인트
# 기본 크기/대기
spring.datasource.hikari.minimum-idle=10 # 유휴(최소) 유지 개수
spring.datasource.hikari.maximum-pool-size=20 # 동시에 빌릴 수 있는 최대
spring.datasource.hikari.connection-timeout=30000 # 빌릴 때 최대 대기(ms)
# 수명/정리
spring.datasource.hikari.idle-timeout=600000 # 유휴 연결 정리(ms)
spring.datasource.hikari.max-lifetime=1800000 # 연결 교체 주기(ms) ← DB wait_timeout보다 살짝 짧게
spring.datasource.hikari.keepalive-time=0 # 필요 시 주기적 keepalive(ms)
# (옵션) 누수 탐지
spring.datasource.hikari.leak-detection-threshold=20000 # 빌리고 안 돌려주면 경고(ms)
스프링/트랜잭션과의 연결
- @Transactional 시작 → 풀에서 커넥션 1개를 빌려 현재 스레드에 바인딩
- 메서드 끝(정상/예외) → commit/rollback 수행 → 풀에 반납
- 같은 트랜잭션 동안엔 항상 같은 커넥션을 사용 (일관성 보장)
initial / max / idle / pooling time 매핑 (Hikari 설정)
그림의 개념 의미 Hikari 속성 (Spring Boot) 설명/팁
그림의 개념 | 의미 | Hikari 속성 (Spring Boot) | 설명/팁 |
initial | 서버 시작/운영 중 미리 확보해 둘 유휴 커넥션 개수 | spring.datasource.hikari.minimum-idle | “최소 유휴 개수”. 이 수만큼은 항상 놀고 있게 유지 → 첫 요청 지연 감소(웜업 효과) |
max | 동시에 빌릴 수 있는 최대 커넥션 | spring.datasource.hikari.maximum-pool-size | 동시 트래픽 상한. 너무 작으면 대기/타임아웃, 너무 크면 DB가 힘들어짐 |
idle | 유휴(놀고 있는) 커넥션 수 | (상동, minimum-idle) + 회수 주기: idle-timeout | 사용 안 하는 연결을 몇 개 유지할지 + 오랫동안 놀면 정리하는 시간(ms) |
pooling time | 커넥션 대기 한도(풀 꽉 찼을 때 얼마나 기다릴지) | spring.datasource.hikari.connection-timeout | 이 시간 안에 못 빌리면 예외(풀 고갈). SLA에 맞춰 짧게 잡아 장애를 빨리 인지 |
반응형