1. 커넥션 누수 현상 확인 방법
1.1 DB 세션 모니터링
DB에서 현재 활성화된 세션을 확인하여, 어플리케이션에서 생성한 세션이 지속적으로 유지되고 있는지 점검
MySQL
SHOW PROCESSLIST;
SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep';
- Sleep 상태의 세션이 많다면 커넥션이 닫히지 않고 유지되고 있는 것일 수 있음.
PostgreSQL
SELECT pid, usename, application_name, client_addr, state FROM pg_stat_activity;
- state가 idle in transaction 상태로 오래 유지되면 커넥션이 닫히지 않은 것.
Oracle
SELECT SID, STATUS, SCHEMANAME, MACHINE, PROGRAM FROM V$SESSION WHERE STATUS = 'ACTIVE';
- 특정 프로그램에서 지속적으로 세션이 유지되는지 확인.
1.2 JDBC Connection 누수 감지 (Active Connection 수 확인)
1) Connection Pool 사용 시 현재 활성 커넥션 수 체크
만약 HikariCP 같은 커넥션 풀을 사용 중이라면, 다음 코드로 현재 커넥션 수를 확인
HikariDataSource hikariDataSource = (HikariDataSource) dataSource; System.out.println("Active connections: " + hikariDataSource.getHikariPoolMXBean().getActiveConnections());
- getActiveConnections() 값이 지속적으로 증가하면 커넥션이 누수되고 있을 가능성이 큼.
2) 직접 Connection 수를 출력하는 코드 추가 (로깅)
try (Connection connection = dataSource.getConnection()) {
System.out.println("DB Connection opened: " + connection);
} catch (SQLException e) {
e.printStackTrace();
}
- 커넥션이 닫히지 않으면 로그를 분석해서 누수를 확인할 수 있음.
2. 누수 원인 및 해결 방법
2.1 Connection Close 누락 여부 점검
JDBC 사용 시 close() 메서드를 호출하지 않으면 커넥션이 유지되므로, 아래 방식처럼 try-with-resources를 사용하여 자동으로 닫히도록 처리할 수 있음.
문제 코드 (Connection 닫지 않음)
Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("name"));
}
// conn.close(); ← 이게 빠지면 누수 발생
올바른 코드 (try-with-resources 사용)
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
- try-with-resources를 사용하면 Connection, PreparedStatement, ResultSet이 자동으로 닫힘.
2.2 Connection Pool 설정 확인
커넥션 풀을 사용할 때, 설정이 잘못되면 커넥션이 닫히지 않고 계속 유지
HikariCP 설정 예시
# HikariCP 설정 (application.properties)
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=2
spring.datasource.hikari.idle-timeout=30000 # 30초 후 유휴 커넥션 종료
spring.datasource.hikari.max-lifetime=1800000 # 30분 후 커넥션 재생성
- idle-timeout을 너무 크게 설정하면 사용되지 않는 커넥션이 유지될 수 있음.
C3P0 설정 예시
spring.datasource.c3p0.max-size=10
spring.datasource.c3p0.max-idle-time=30 # 30초 후 유휴 커넥션 종료
2.3 오랜 트랜잭션 방지
commit() 또는 rollback()을 하지 않으면 트랜잭션이 유지되면서 커넥션이 반환되지 않는 경우가 있음.
문제 코드 (트랜잭션 종료 누락)
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement("UPDATE users SET name = ? WHERE id = ?");
ps.setString(1, "NewName");
ps.setInt(2, 1);
ps.executeUpdate();
// conn.commit(); ← 빠지면 커넥션이 계속 유지됨
conn.close();
올바른 코드
try (Connection conn = dataSource.getConnection()) {
conn.setAutoCommit(false);
try (PreparedStatement ps = conn.prepareStatement("UPDATE users SET name = ? WHERE id = ?")) {
ps.setString(1, "NewName");
ps.setInt(2, 1);
ps.executeUpdate();
}
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
- 트랜잭션을 사용하면 반드시 commit() 또는 rollback()을 호출해야 함.
2.4 Debugging: Connection Leaks 추적
HikariCP LeakDetectionThreshold 설정
HikariCP를 사용한다면, 누수되는 커넥션을 감지할 수 있도록 설정
spring.datasource.hikari.leak-detection-threshold=2000 # 2초 이상 사용된 커넥션 로그 출력
- 2초 이상 반환되지 않는 커넥션이 있으면 로그로 감지 가능.
Apache Commons DBCP Debug 설정
DBCP를 사용 중이라면, logAbandoned=true 옵션을 활성화해서 누수된 커넥션을 감지할 수 있어.
spring.datasource.dbcp2.log-abandoned=true
spring.datasource.dbcp2.remove-abandoned-on-maintenance=true
spring.datasource.dbcp2.remove-abandoned-on-borrow=true
spring.datasource.dbcp2.remove-abandoned-timeout=60
3. 결론
✅ DB에서 활성 세션 확인 (SHOW PROCESSLIST;, pg_stat_activity, V$SESSION)
✅ JDBC에서 Connection, Statement, ResultSet을 닫고 있는지 확인 (try-with-resources 사용)
✅ 커넥션 풀 설정 확인 (idle-timeout, max-lifetime)
✅ 트랜잭션이 commit/rollback 없이 유지되고 있는지 점검
✅ LeakDetectionThreshold 또는 logAbandoned 설정으로 커넥션 누수 감지
'프로그래밍' 카테고리의 다른 글
SaaS로 전환하는 이유와 IT 운영자의 대응방안 (0) | 2025.03.22 |
---|---|
SaaS Vs 온프레미스(On-Premise) 비교, Hybrid SaaS (0) | 2025.03.21 |
클라우드 완벽 정리: 개념, 종류, 장점, 기술, 보안, 활용 사례 (1) | 2025.03.18 |
오라클에서 특수문자(&, ', ", %, @ 등)를 INSERT할 때 주의할 점과 처리 방법 (2) | 2025.03.17 |
[WAS] JEUS Vs Tomcat 비교, 네이버와 같은 서비스 IT 회사에서는 Tomcat을 사용하는 이유 (1) | 2025.03.01 |