갑자기 프론트에서 API 사용이 안 된다고해서 배포서버 로그를 확인했다.

사용 가능한 커넥션 풀이 없다고 나왔다.
근데 커넥션 풀이 뭘까..?
애플리케이션이 DB에 접근하려면, 먼저 네트워크를 통해 DB 서버와 연결(Connection)을 맺어야 한다. 이 연결이 쿼리를 생성할때마다 일어나면 성능이 매우 떨어지기에, 한 번 만들어두고 재사용을 하게 된다.
즉 커넥션 풀은 DB 커넥션을 미리 만들어두고, 필요할 때 빌려 쓰는 풀(pool)이다.
① 커넥션 누수 (Connection Leak)
코드 내부에서 DB 커넥션을 가져간 뒤, 어떤 이유로든 반납(close())하지 않고 계속 붙잡고 있는 경우
Spring Boot와 JPA(Spring Data JPA)를 쓰면 기본적으로 트랜잭션이 끝날 때 커넥션을 알아서 반납하지만, Transaction 범위를 벗어난 곳에서 Lazy Loading을 과도하게 시도하거나 외부 API 호출처럼 시간이 오래 걸리는 작업이 트랜잭션 내부(또는 OSIV 구조)에 묶여 있을 때 발생 가능
② 느린 쿼리 (Slow Query)와 병목
특정 API가 실행하는 쿼리가 너무 느려서 커넥션을 수초 동안 붙잡고 있는 경우
인덱스가 타지 않는 대량의 조인 쿼리나 전체 테이블 스캔이 발생하면, 하나의 요청이 커넥션을 오래 점유하게 되고, 뒤이은 요청들이 줄줄이 대기하다가 풀이 고갈됨
③ 데드락 (Deadlock)
두 개 이상의 트랜잭션이 서로가 가진 데이터 락(Lock)이 풀리기를 기다리며 무한 대기에 빠지는 상황
내 경우는 아마 1번인것 같다.
application.yaml에 hikari 설정을 추가했다.
spring:
main:
allow-bean-definition-overriding: true
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 10
minimum-idle: 10
idle-timeout: 300000
max-lifetime: 480000
keepalive-time: 240000
connection-test-query: "SELECT 1"
validation-timeout: 3000