배포 후 응답 지연? JVM 웜업으로 해결!
배포 직후 DB Connection Timeout 및 응답 지연 문제 발생, HikariCP 설정 변경 시도
JVM 웜업(Warm-up)을 통해 애플리케이션 구동 시 필요한 클래스들을 미리 로딩
웜업 적용 후, 응답 시간(Response Time) 안정화 및 트래픽 증가에도 문제없이 대응
웜업 적용 전, 클래스 로딩 지연(Class Loading Delay)이 초기 응답 지연의 원인임을 확인
K8s 기반 배포 파이프라인에 StartupProbe 추가하여 웜업 완료 후 트래픽 유입
HikariCP 커넥션 타임아웃(Connection Timeout) 문제 분석
본문에서는 배포 후 발생하는 DB Connection Timeout 에러의 원인을 HikariCP의 설정 문제로 보고, 옵션 변경을 시도했음을 설명한다.
connectionTimeout: 커넥션 풀에서 커넥션을 얻기 위해 대기하는 최대 시간, 10초로 설정
maximumPoolSize: 커넥션 풀의 최대 커넥션 개수, 30개로 설정
minimumIdle: 유휴 커넥션의 최소 개수
최대 커넥션 개수를 늘렸음에도 문제가 해결되지 않자, JVM 웜업(Warm-up)을 통해 근본적인 원인을 찾으려는 시도를 보여준다.
JVM 웜업(Warm-up) 적용 방법
굿딜 서비스는 ApplicationRunner를 사용하여 애플리케이션 구동 후 웜업 코드를 실행하도록 구현했다. 또한, K8s 기반 배포 파이프라인에 StartupProbe를 추가하여 웜업 완료 여부를 확인한 후 트래픽을 유입하도록 설정했다.
ApplicationRunner: 스프링 애플리케이션 구동 후 실행될 빈(Bean) 정의
StartupProbe: 컨테이너 내 애플리케이션 기동 여부 확인, 웜업 완료 전까지 다른 프로브 비활성화
웜업 대상: 굿딜 전체 브랜드 조회 로직 및 추천 브랜드 조회 로직 호출
이러한 과정을 통해 배포 직후의 초기 응답 지연 문제를 해결하고, 서비스 안정성을 확보했다.
클래스 로딩(Class Loading) 지연 문제의 근본 원인
글에서는 웜업 적용 전, 초기 응답 지연의 원인이 클래스 로딩 지연(Class Loading Delay)에 있음을 분석한다. 실제 HTTP 요청 처리 및 DB 통신에 필요한 라이브러리 클래스들이 첫 요청 시 로딩되면서, 커넥션 점유 시간 증가 및 커넥션 풀 고갈을 유발했다는 것이다.
-Xlog:class+load=info:file=classloading.log: JVM 옵션을 통해 클래스 로딩 로그 확인
스프링 컨테이너(Spring Container)에 의해 관리되는 빈(Bean)들은 웜업 대상 아님
실제 HTTP 요청 처리 및 DB 통신 관련 클래스들이 지연 로딩됨을 확인
결과적으로, 웜업을 통해 이러한 지연 로딩을 해결하여 초기 응답 속도를 개선했다.
웜업 적용 후 성능 지표 변화
웜업 적용 후, 굿딜 서비스는 Connection Usage Time, Connection Acquire Time, HikariCP connection pool, API 응답 속도(Response Time) 등 주요 지표에서 긍정적인 변화를 보였다.
Connection Usage Time: 2ms 내로 안정화
Connection Acquire Time: 원활한 획득 확인
HikariCP connection pool: 커넥션 사용량 원활
API 응답 속도: 안정적인 응답 유지
이러한 지표 개선을 통해, 웜업이 초기 응답 지연 문제를 해결하는 데 효과적이었음을 입증했다.
JIT 컴파일러(JIT Compiler)와 웜업의 관계
본문에서는 웜업의 두 가지 목표, 즉 클래스 로딩과 JIT 컴파일링에 대해 설명하며, 더 높은 성능을 위해서는 JIT 컴파일러를 활용한 최적화가 필요하다고 강조한다.
JIT 컴파일러: 바이트 코드를 네이티브 기계어로 컴파일하여 애플리케이션 성능 향상
HotSpot VM: 런타임에 자주 호출되는 메서드(Hot Spot)를 식별하여 네이티브 기계어 저장
Tiered Compilation: 여러 단계의 최적화 적용 (Level 0~4)
GraalVM Native Image: AOT(Ahead Of Time) 기술을 활용한 네이티브 코드 컴파일
결론적으로, 웜업은 초기 지연 해결에 효과적이지만, 더 높은 수준의 성능을 위해서는 JIT 컴파일러의 임계값을 고려한 웜업 또는 AOT 기술을 활용해야 한다.