HikariCP Connection Leak: AbandonedConnectionCleanupThread 원인 분석 및 해결 방안

🤖 AI 추천

이 콘텐츠는 Spring Boot 환경에서 HikariCP를 사용하며 데이터베이스 커넥션 풀 관리 시 발생할 수 있는 메모리 누수 문제를 해결하고자 하는 백엔드 개발자에게 특히 유용합니다. GC 수행 후에도 Heap 사용량이 줄어들지 않아 메모리 누수를 의심하는 상황에서 Heap Dump 분석부터 문제 원인인 AbandonedConnectionCleanupThread의 동작 방식 이해, 그리고 HikariCP max-lifetime 설정이나 비활성화와 같은 실질적인 해결책까지 단계별로 안내하고 있어 경험 수준에 관계없이 많은 개발자들에게 도움이 될 것입니다.

🔖 주요 키워드

HikariCP Connection Leak: AbandonedConnectionCleanupThread 원인 분석 및 해결 방안

핵심 기술

이 글은 Spring Boot 환경에서 발생하는 Heap 사용량 증가 및 메모리 누수 현상의 근본 원인을 HikariCP의 AbandonedConnectionCleanupThread에서 찾고, Heap Dump 분석을 통해 이를 진단하며 해결책을 제시합니다.

기술적 세부사항

  • 문제 상황: GC 수행 후에도 Heap 사용량이 줄어들지 않고 특정 서버들에서 지속적으로 높은 사용량을 보이는 현상 발생.
  • 메모리 누수 진단:
    • Grafana 대시보드를 통해 Heap 사용량 및 GC 로그를 확인하여 GC는 정상 수행됨을 예측했으나, 특정 서버의 높은 Heap 사용량으로 메모리 누수 의심.
    • jps 명령어로 JVM 프로세스 확인 후, jmap -dump:file=application.hprof <PID> 명령어로 Heap Dump 생성.
    • Eclipse Memory Analyzer (MAT)를 사용하여 Heap Dump 분석.
  • 원인 분석:
    • Heap Dump 분석 결과, MySQL Connection 및 abandoned connection cleanup 관련 내용 발견.
    • AbandonedConnectionCleanupThread는 명시적으로 닫히지 않은 MySQL 커넥션을 닫아주는 역할을 하며, 단일 스레드로 동작함.
    • NetworkResources.forceClose() 메서드에서 입출력 스트림 종료 및 소켓을 닫는 과정에서 네트워크 환경에 따라 병목 발생 가능.
    • 이 병목 현상이 AbandonedConnectionCleanupThread에 쌓이는 AbandonedConnection을 증가시키고, 결과적으로 Heap 사용량 증가로 이어짐.
  • 발생 조건: HikariCP의 max-lifetime 설정이 짧을 때, 무중단 배포 등으로 인해 "Sleep" 상태의 커넥션이 남을 수 있으며, 이로 인해 AbandonedConnectionCleanupThread의 부하 증가.
  • 해결 방안:
    1. HikariCP max-lifetime 조정: 기본값인 30분 등으로 길게 설정하여 AbandonedConnection 축적 속도 완화.
    2. AbandonedConnectionCleanupThread 비활성화:
      • com.mysql:mysql-connector-j 버전 8.0.22 이상으로 업그레이드.
      • JVM 실행 옵션에 -Dcom.mysql.cj.disableAbandonedConnectionCleanup=true 추가.
  • AbandonedConnectionCleanupThread의 존재 이유: 레거시 프로젝트와의 호환성, 특히 jdbc 또는 dbcp2 등 사용 시 닫히지 않은 커넥션 관리에 유용함.

개발 임팩트

  • 데이터베이스 커넥션 풀 관리의 효율성 증대.
  • 애플리케이션의 안정성 및 성능 개선 (Heap 사용량 정상화, 메모리 누수 방지).
  • 문제 해결 과정을 통해 Java 메모리 관리 및 JVM 튜닝에 대한 이해도 향상.

커뮤니티 반응

  • 글에서는 직접적인 커뮤니티 반응은 언급되지 않았으나, serverfault #1070128과 같은 외부 자료를 인용하여 문제 상황의 일반성을 뒷받침합니다.

📚 관련 자료