반응형
프로젝트를 진행하는 당시 백엔드에서 모델 서버에 여러 번 Sagemaker Endpoint로 요청을 호출했을 때, 갑자기 EC2에서 해당 로그를 뜯어봤을 때 다음과 같은 에러가 발생했다.
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30001ms (total=10, active=10, idle=0, waiting=0)
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:686) ~[HikariCP-5.1.0.jar!/:na]
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:179) ~[HikariCP-5.1.0.jar!/:na]
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:144) ~[HikariCP-5.1.0.jar!/:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:127) ~[HikariCP-5.1.0.jar!/:na]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-6.5.2.Final.jar!/:6.5.2.Final]
at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:46) ~[hibernate-core-6.5.2.Final.jar!/:6.5.2.Final]
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:113) ~[hibernate-core-6.5.2.Final.jar!/:6.5.2.Final]
... 121 common frames omitted
2024-11-13T19:55:32.633Z ERROR 1 --- [io-8080-exec-12] g.o.h.OAuth2AuthenticationFailureHandler : error : Unable+to+acquire+JDBC+Connection+%5BHikariPool-1+-+Connection+is+not+available%2C+request+timed+out+after+30001ms+%28total%3D10%2C+active%3D10%2C+idle%3D0%2C+waiting%3D0%29%5D+%5Bn%2Fa%5D
HikariCP Connection 고갈 문제는 데이터베이스 연결이 충분히 반환되지 않아 발생하는 일반적인 문제이다.
원인 분석
- 데이터베이스 연결 미반환
- 트랜잭션이 끝나기 전에 데이터베이스 연결이 반환되지 않거나, 연결이 반환되지 않는 Connection Leak이 발생할 수 있다.
- 동시성 문제:
- 동시 접속이 많은 경우, HikariCP의 maxPoolSize가 초과되어 연결이 고갈될 수 있다.
- 비효율적인 쿼리 또는 잠금
- 특정 쿼리가 너무 오래 걸리거나 테이블 잠금이 발생하는 경우, 데이터베이스 연결이 장시간 점유될 수 있다.
해결 방안
- HikariCP 설정 조정
application.properties 또는 application.yml 파일에서 HikariCP 설정을 조정하여 풀의 크기와 타임아웃을 최적화할 수 있다.
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)
- Connection Leak Detection
leakDetectionThreshold 옵션을 사용해 누수된 연결을 감지할 수 있다.
예를 들어, 2초 동안 반환되지 않은 연결이 있을 경우 경고 로그를 기록하도록 설정할 수 있다.
spring.datasource.hikari.leak-detection-threshold=2000 # 2초 이상의 연결 점유를 leak으로 간주
- 코드 검토 및 트랜잭션 관리
- 데이터베이스 작업이 끝난 후 반드시 Connection이 반환되도록 try-with-resources 또는 @Transactional을 올바르게 사용하고 있는지 확인하기.
- @Transactional이 올바르게 적용되지 않으면 트랜잭션이 종료되지 않고 커넥션을 점유할 수 있으니 주의!
- 쿼리 최적화
- 오래 걸리는 쿼리를 최적화하고, 인덱스를 사용하여 데이터베이스 성능을 개선.
- 특히, 잠금 발생 가능성이 있는 테이블에 인덱스를 추가하거나 쿼리를 최적화하여 동시 처리 성능을 개선한다.
- 최대 풀 사이즈 재조정
- maximum-pool-size를 서버와 데이터베이스가 감당할 수 있는 범위에서 충분히 크게 설정한다.
- 그러나 풀 크기를 너무 크게 설정하면 서버의 메모리 자원이 부족할 수 있으므로 주의.
참고
HikariCP Connection 고갈 문제
발단 프로젝트 서버를 운영하는 과정에서 SSE로 알림을 구현하고 서버에 적용하였다. 사용자가 로그인하여 SSE로 연결이 되면, 이전에 저장해놓은 모든 알림을 사용자에게 보내는 기능도 추가하
velog.io
반응형
'Infra & Cloud' 카테고리의 다른 글
[Apache Kafka] Kafka Producer의 데이터 멱등성 보장하기 (0) | 2025.03.26 |
---|---|
[Apache Kafka] kafka 파헤치기 (2) | 2025.03.25 |
[Nginx] 413 Request Entity Too Large 오류 (0) | 2024.11.27 |