본문 바로가기
컴퓨터/네트워크

DB 커넥션 풀(Connection Pool) 관리 | 적정 풀 사이즈, 각종 타임아웃, 커넥션 누수

by 버니케이 2026. 6. 14.
반응형



이번에 이런 일이 있었는데
하필 서버시간이 부족해서 DB 커넥션 풀을 확인하지 못했다.

https://gallery-k.tistory.com/494
그래서 이번주에 한번 더 찾아가서 볼 예정인데, 그전에 DB 커넥션을 좀 공부해보려고 한다. 


커넥션 풀


애초에 커넥션 풀이 왜 필요할까? (L4와 TCP의 한계)

TCP 통신은 꼼꼼해서 
매번 '3-Way Handshake(인사 3번)'를 한다.
- '나 데이터 보낸다? 준비됐어?'

- '어 받을 준비됐어! 너도 보낼 준비됐지?'
- '응 준비끝! 이제진짜 보낸다!'

 


백엔드 서버가 DB에 쿼리를 날릴 때도 똑같다. 
유저가 로그인 버튼을 누를 때마다 
서버가 DB랑 3-Way Handshake(인사 3번)' 을 한다. 

그런데 매번 데이터를 받아올 때마다

"안녕? 연결할게 / 응 연결해 / 오케이 쿼리 보낸다"를 반복하면 
데이터 조회보다 연결 맺는 시간이 더 오래 걸린다.

그래서 백엔드 서버가 켜질 때, 
미리 DB랑 TCP 연결(소켓)을 10개~20개 정도 맺어두고 수영장(Pool)에 둥둥 띄워 놓는다.
유저 요청이 오면 만들어둔 연결을 빌려주고, 다 쓰면 다른 요청이 쓸 수 있게 만드는 것이다. 
이것이 커넥션 풀의 존재 이유이다.


 

3-Way Handshake(인사 3번) 을 새 튜브에 입으로 열심히 바람을 불어 넣는 작업이라고 쳤을 때

다 쓴 튜브의 바람을 빼버리면(연결 종료),

다음 유저가 왔을 때 또 입으로 바람을 불어야 한다. 

 

그래서 커넥션 풀을 10으로 설정했다고 가정한다면

 

서버 시작 시: 

튜브 10개에 땀을 뻘뻘 흘리며 바람을 빵빵하게 채워서 수영장에 띄워 둔다. 

유저 요청 (빌림): 

유저 10명이 와서 튜브 10개를 타고 재밌게 논다. 

유저 반납 (close()):

유저가 다 놀고 나간다.

다시 빌려줌 (재사용) :

튜브의 바람을 빼지 않고(TCP 연결을 끊지 않고) 물 위에 그대로 띄워 뒀다가, (반납)

다음 손님이 오면 그 튜브를 바로 사용한다.

 


예시( HikariCP )


HikariCP 로 예시를 들어서 보면은 다음과 같다.

1. 적정 풀 사이즈 (Maximum Pool Size) 구하기
"수영장에 튜브(커넥션)를 몇 개 띄워둘 것인가?"

 


"트래픽이 많으니까 튜브를 100개, 1,000개 띄워두면 무조건 빠르겠지?" 
라고 생각할 수 있는데 절대 아니다. 
DB 서버의 CPU 코어 수, 메모리 한계를 넘어가면 
오히려 튜브끼리 부딪히느라(컨텍스트 스위칭) DB가 뻗어버린다. 

사내코드보니까 8개였다


보통 실무에서는 
10~50개 사이로 계산해서 설정한다.
(우아한형제들이나 카카오 기술 블로그를 참고해서 아니면 ai 한테 물어봐서...?)

 



2. 각종 타임아웃(Timeout) 설정의 의미


connection-timeout: 
    유저가 몰려서 수영장에 남은 튜브가 없을 때, 유저를 몇 초 동안 밖에서 기다리게 할 것인가? 
    (보통 30초 넘어가면 그냥 에러 뱉게 만든다.)

max-lifetime: 
    하나의 커넥션(튜브)을 최대 몇 분 동안 재사용하고 폐기할 것인가?

max-lifetime  과 L4와의 관계: 
보통 회사 인프라의 방화벽이나 L4 라우터는 
"아무 통신 없이 15분 이상 켜져 있는 TCP 소켓은 죽은 걸로 간주하고 강제로 끊어버린다"는 룰이 있다. 
그래서 백엔드 개발자는 이 장비들의 규칙을 파악하고, 
그보다 짧은 시간(10분)마다 튜브를 새것으로 교체해 주도록 
max-lifetime을 설정해야 DB 연결 끊김(DB Connection Closed) 에러를 막을 수 있다.



3. 커넥션 누수 


튜브를 빌려 갔는데 반납(close())을 안 했을 때...

꼭 close 를 해야한다. 

 

그치만 요즘은 Spring Data JPA나 MyBatis 같은 프레임워크가 

쿼리가 끝나면 알아서 튜브를 반납해 준다. 

 


하지만 외부 API를 찌르고 오래 기다리거나, 트랜잭션(@Transactional) 범위가 너무 넓으면 
나 혼자 튜브를 10초, 20초씩 독점하게 되어 다른 유저들이 튜브를 못타고 밖에서 무한 대기하게된다. 
그래서 트랜잭션 범위를 최소화해야된다. 

 

반응형

댓글