728x90

0.개요
Spring Boot에서는 DB Connection을 자동으로 처리해줘서 별로 신경안쓰고있었기 때문에 이번기회에 알아보고자한다.
1. DB Connection이란
WAS와 데이터베이스 서버 간에 데이터를 주고받기 위해 만들어진 통신 경로이자 세션이다.
클라이언트가 DB에 데이터를 요청, 수정하기 위해 인증 과정을 거쳐 세션을 생성하고 유지하는 과정이다.

2. DB Connection LifeCycle
2-1.연결 요청
우선은 애플리케이션이 DB 서버의 주소(IP/Port), 접속 계정, 비밀번호 등 인증 정보를 보내며 연결을 요청합니다
2-2.인증 및 통신로 개설
DB 서버가 자격 증명을 확인하고, 접근을 허락하면 둘 사이에 데이터를 안전하게 주고받을 수 있는 전용 통신로(TCP/IP 소켓같은거)가 열립니다.
2-3.데이터 교환
연결된 통로를 통해 애플리케이션은 SQL 쿼리를 보내고, DB는 그에 맞는 결과 데이터를 응답으로 돌려줍니다.
2-4.연결 종료
데이터 처리가 모두 끝나면, 다른 프로그램들이 DB를 원활하게 사용할 수 있도록 열어두었던 연결을 명시적으로 끊어줍니다.
이과정이 중요한게 연결종료를 안하면 누수된다...
3.커넥션 누수(Connection Leak)
앞에서 연결종료단계가 중요하다고 했는데 이걸 안하게 되면 연결이 계속 이어지게된다.
커넥션이 하나 유지될 때마다 WAS와 DB 양쪽 서버 모두에서 메모리와 네트워크 포트를차지하게 되는데 이는 심하면 Out Of Memory까지 일어날수있다....
또한 연결을 안끊으면 결국 DB 최대 연결 수에 도달하여 새로운 연결을 못하여 DB에 연결자체를 못하는 상황까지 올수있는것이다...

4.커넥션 풀(Connection Pool)이란?
앞에 말했던 Connection을하고 끊는 과정은 LifeCycle만 봐도 계속 반복해서 일어날경우 서버에 리소스를 소모시킬것처럼 보인다. 때문에 등장한것이 미리 만들어 두고 그것을 재활용하고 돌려쓰는 커넥션 풀(Connection Pool)이다.

5.커넥션 풀(Connection Pool)의 방식
5-1.사전 준비
WAS가 처음 켜질 때 미리미리 DB Connection을 정해진 개수만큼 만들어둔다! 그리고 이를 별도로 저장하여 관리해준다.
5-2.대여
WAS는 이제 새로운 DB Connection을 만드는게 아니라, 연결할상황이 생기면 만들어진 Connection Pool중 하나를 사용한다
5-3.반납
데이터 조회가 끝나면 기존 DB Connection에서 연결을 끊는것처럼 끊는게 아니라 연결 자체는 남기고 풀에 반납만 한다.
동일하게 이또한 수행하지않으면 Connection Leak로 Pool의 남은 개수가 점점 줄어들것이고 결국 풀 고갈상태가 되어 결국 Pool을 사용못하는 상황이 오게될수있다.
Connection conn = dataSource.getConnection();
try {
// 만약 여기서 에러가 발생한다면?
int result = stmt.executeUpdate("INSERT INTO ...");
conn.close(); // 실행되지 못하고 건너뛰게 됨 -> 누수 발생!
} catch (Exception e) {
logger.error("에러 발생", e);
}
6.커넥션 풀(Connection Pool)을 왜쓰는가! 장점!
6-1. 불필요한 Connection 오버헤드 감소
연결 생성/종료이 불필요하니까 사용자가 느끼는 응답 속도가 빨라지고 서버측 부하도 줄어든다.
6-2. 서버 보호
풀의 최대 크기를 미리 정해두고 운용할수있으므로 트래픽이 폭주해도 풀을 넘는 작업들은 대기열에 넣는 방식으로 서버측의 부하를 줄일수있다.
7. Java의 DataSource란?
이러한 DB Connection은 원래 DriverManager를 사용했었다고 한다.
나도 예전에 한번 공부겸 DriverManager를 사용해봤는데 정말 끔찍한 경험이였다...
7-1. DriverManager 방식
DriverManager을 사용할때는 커넥션 풀을 전혀 사용하지않고 매 연결 코드마다 새로운 DiverManger을 세팅하고 연결하는 방식을 사용했었다. 당연히 유지보수가 힘들고, 코드도 보기어려웠다.
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "myId";
String password = "myPassword";
try {
//호출할 때마다 DB와 새롭게 네트워크 통신을 시도함
Connection conn = DriverManager.getConnection(url, user, password);
// DB 작업 수행
} catch (SQLException e) {
e.printStackTrace();
}
7-2. DataSource 방식
반대로 DataSource는 다음처럼 글로벌하게 미리 세팅을 해둔뒤 Pool로 커넥션을 미리 만들어둔다.
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("myId");
dataSource.setPassword("myPassword");
dataSource.setMaximumPoolSize(10); // 미리 만들어둘 커넥션 개수
그러면 이제 직접 사용할때는 다음처럼 간단한 코드로 Connection을 사용할수 있는거다.
try {
Connection conn = dataSource.getConnection();
// DB 작업 수행...
} catch (SQLException e) {
e.printStackTrace();
}
8. 커넥션의 최대연결 시간의 함정
8-1.Idle Timeout
Idle Timeout은 놀고있는 Connection을 끊어버리는것을 의미한다. 어플리케이션에서 Idle Timeout이 일어나면 서버 리소스도 줄이고 나중에 필요할때 다시 생성하면 되니까 좋은게 아닌가? 라고 생각할수도있다. 하지만 WAS 밖에서의 문제가 있다.
Idle Timeout은 WAS 뿐만 아니라 네트워크 장비(방화벽, L4 스위치), DB서버에서도 발생할수있다.
만약 WAS에서 5분으로 Idle Timeout이 설정되고, 네트워크 장비에서 3분으로 설정된다면
네트워크장비쪽에서는 3분뒤 연결을 끊지만 WAS에서는 아직 2분정도 연결을 계속 지속하는 상황이 발생하게 된다.

그러면 사용자가 DB요청을 사용하면 WAS는 정상적으로 아직 pool을 사용가능하다고 인식하고 사용하지만 실제로 네트워크장비에서는 연결이 이미 끊겼기때문에 정상적인 작동이 불가능한 상태가 되버린다.
8-2.Communications link failure 오류, Broken pipe오류
소켓 통신(네트워크)에서 송신자가 데이터를 보내려는데 수신자(클라이언트)가 이미 연결을 끊었거나 비정상적으로 종료되어, 데이터를 전달할 곳이 없어 발생하는 Broken pipe오류,
애플리케이션(Java 등)이 MySQL 데이터베이스에 연결을 시도했으나, 네트워크 차단, DB 종료 또는 타임아웃으로 인해 통신이 끊겼을때 나오는 오류 Communications link failure 오류를 겪을수있다.

8-3. 해결법
실제 HikariCP에서는 Configuration 섹션의 maxLifetime을 다음처럼 권장한다.
실제 사용할때는 안정성을 생각해서 30초에서 길게는 2~3분까지는 앞당겨 설정하는게 일반적이다.
We strongly recommend setting this value, and it should be several seconds shorter than any database or infrastructure imposed connection time limit
이 값을 설정하는 것을 강력히 권장하며, 데이터베이스나 인프라가 강제하는 커넥션 제한 시간보다 수 초 정도 짧게 설정해야 합니다

728x90
'Computer Science > DataBase' 카테고리의 다른 글
| [DB] 인덱스(Index)에 대해 (0) | 2026.07.10 |
|---|---|
| [DataBase] Oracle Long 타입, 생소한 DB타입들 정리 (0) | 2026.07.02 |
| [DataBase] Oracle Vscode 에서 사용하기 (0) | 2025.05.25 |