Contents
see List개요
CRaC(Coordinated Restore at Checkpoint)는 OpenJDK의 실험적 기능으로, JVM의 실행 상태를 스냅샷으로 저장하고 빠르게 복원하여 애플리케이션 시작 시간을 밀리초 수준으로 단축합니다. Spring Boot 3.5는 CRaC를 공식 지원하며, 서버리스 환경과 Auto-scaling 시나리오에서 콜드 스타트 문제를 해결합니다. 이 문서에서는 CRaC의 원리와 Spring Boot 통합 방법을 다룹니다.
CRaC 작동 원리
CRaC는 애플리케이션을 "워밍업"된 상태로 체크포인트하고, 이후 시작 시 해당 시점부터 복원합니다. 이를 통해 클래스 로딩, 스프링 컨텍스트 초기화, 데이터베이스 연결 등의 시간을 생략할 수 있습니다.
- Checkpoint: 애플리케이션이 완전히 초기화된 후 메모리 상태를 디스크에 저장
- Restore: 저장된 스냅샷에서 즉시 복원하여 요청 처리 시작
- 효과: 10초 → 100ms로 시작 시간 단축 (100배 개선)
CRaC 활성화 환경 구성
CRaC를 사용하려면 특수 빌드된 OpenJDK가 필요합니다.
# CRaC 지원 OpenJDK 다운로드
wget https://github.com/CRaC/openjdk-builds/releases/download/17-crac+5/openjdk-17-crac+5_linux-x64.tar.gz
tar -xzf openjdk-17-crac+5_linux-x64.tar.gz
export JAVA_HOME=$(pwd)/openjdk-17-crac+5
# 애플리케이션 빌드
./mvnw clean package -DskipTests
# Checkpoint 생성 (sudo 필요)
sudo $JAVA_HOME/bin/java -XX:CRaCCheckpointTo=cr \
-jar target/myapp-0.0.1-SNAPSHOT.jar
# Restore로 빠른 시작
sudo $JAVA_HOME/bin/java -XX:CRaCRestoreFrom=crSpring Boot CRaC 통합
Spring Boot 3.2+부터 @Checkpoint 및 @Restore 라이프사이클 훅을 지원합니다.
<dependency>
<groupId>org.crac</groupId>
<artifactId>crac</artifactId>
<version>1.4.0</version>
</dependency>@Component
public class CRaCLifecycleBean implements Resource {
private Connection dbConnection;
@PostConstruct
public void init() {
// 체크포인트 리소스 등록
Core.getGlobalContext().register(this);
}
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
// Checkpoint 전 정리 작업
System.out.println("Closing connections before checkpoint...");
if (dbConnection != null && !dbConnection.isClosed()) {
dbConnection.close();
}
}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception {
// Restore 후 재연결
System.out.println("Restoring connections after restore...");
dbConnection = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/mydb",
"user",
"password"
);
}
}데이터베이스 연결 처리
HikariCP 같은 Connection Pool은 Checkpoint 전에 반드시 정리해야 합니다.
@Configuration
public class DataSourceCRaCConfig {
@Bean
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
ds.setUsername("user");
ds.setPassword("password");
// CRaC 이벤트 등록
Core.getGlobalContext().register(new Resource() {
@Override
public void beforeCheckpoint(Context<? extends Resource> context) {
System.out.println("Closing HikariCP pool...");
ds.close();
}
@Override
public void afterRestore(Context<? extends Resource> context) {
System.out.println("HikariCP will auto-reconnect on first query");
// HikariCP는 첫 쿼리 시 자동 재연결
}
});
return ds;
}
}서버리스 환경 통합
AWS Lambda, Google Cloud Run 등 서버리스 환경에서 CRaC 이미지를 활용합니다.
# Dockerfile
FROM ubuntu:22.04
# CRaC OpenJDK 설치
RUN wget https://github.com/CRaC/openjdk-builds/releases/download/17-crac+5/openjdk-17-crac+5_linux-x64.tar.gz && \
tar -xzf openjdk-17-crac+5_linux-x64.tar.gz && \
mv openjdk-17-crac+5 /opt/jdk
# 애플리케이션 복사
COPY target/myapp.jar /app.jar
# Checkpoint 생성 (빌드 시 한 번만)
RUN /opt/jdk/bin/java -XX:CRaCCheckpointTo=/cr -jar /app.jar & \
sleep 30 && \
jcmd myapp.jar JDK.checkpoint
# Restore로 시작
CMD ["/opt/jdk/bin/java", "-XX:CRaCRestoreFrom=/cr"]주의사항과 제약
- Linux만 지원: 현재 CRaC는 Linux 환경에서만 작동합니다. (Windows/macOS 미지원)
- 파일 디스크립터: 열린 파일, 소켓은 Checkpoint 전에 정리해야 합니다.
- 암호화 키: SecureRandom 등의 암호화 상태는 Restore 후 재초기화가 필요합니다.
- 시간 의존성: Checkpoint 시점의 타임스탬프를 캐싱하면 Restore 후 오래된 시간이 사용될 수 있습니다.
- 네이티브 라이브러리: JNI를 사용하는 라이브러리는 CRaC와 호환되지 않을 수 있습니다.
활용 팁
- 서버리스 최적화: 콜드 스타트가 10초에서 100ms로 단축되어 Lambda 비용이 크게 절감됩니다.
- Auto-scaling: 트래픽 급증 시 새 인스턴스가 즉시 요청을 처리할 수 있어 응답 시간이 안정화됩니다.
- 테스트 환경: 통합 테스트에서 애플리케이션을 빠르게 재시작하여 테스트 속도를 개선할 수 있습니다.
- Spring Cloud: Config Server, Service Discovery와 함께 사용 시 Restore 후 재등록 로직을 추가해야 합니다.
- 프로덕션 검증: Checkpoint 이미지는 환경별(dev/stage/prod)로 분리하여 관리해야 합니다.
마무리
CRaC는 Spring Boot 애플리케이션의 시작 시간을 혁신적으로 단축하여 서버리스와 클라우드 네이티브 환경에서 게임 체인저가 될 수 있습니다. 아직 실험적 단계이지만, Spring Framework 팀의 적극적인 지원 덕분에 프로덕션 환경에서도 점차 도입이 증가하고 있습니다. 특히 콜드 스타트 비용이 큰 서버리스 애플리케이션이나 빠른 스케일 아웃이 필요한 마이크로서비스에서 즉각적인 효과를 볼 수 있습니다. 다만 리소스 정리와 복원 로직을 신중히 설계해야 하며, 철저한 테스트가 필수입니다.