Lambda SnapStart용 Java 런타임 훅
Lambda SnapStart용 Java 런타임 훅 (Lambda SnapStart runtime hooks for Java)
런타임 훅(runtime hooks)을 사용해 Lambda가 스냅샷을 만들기 전이나 Lambda가 스냅샷에서 함수를 재개한 후에 실행할 코드를 구현할 수 있어요. 런타임 훅은 오픈소스 CRaC(Coordinated Restore at Checkpoint) 프로젝트의 일부로 제공돼요. CRaC는 Open Java Development Kit(OpenJDK)에서 개발 중이에요. 참조 애플리케이션과 함께 CRaC를 사용하는 예시는 GitHub의 CRaC 저장소를 참고하세요. CRaC는 세 가지 주요 요소를 사용해요.
Resource—beforeCheckpoint()와afterRestore()두 메서드가 있는 인터페이스예요. 스냅샷 전과 복원 후에 실행할 코드를 이 메서드들로 구현해요.Context <R extends Resource>— 체크포인트·복원 알림을 받으려면Resource가Context에 등록되어야 해요.Core— 조정 서비스(coordination service)로, 정적 메서드Core.getGlobalContext()를 통해 기본 전역Context를 제공해요.
Context와 Resource에 대한 자세한 내용은 CRaC 문서의 Package org.crac을 참고하세요.
org.crac 패키지로 런타임 훅을 구현하려면 다음 단계를 따라요. Lambda 런타임은 체크포인트 전과 복원 후에 런타임 훅을 호출하는 사용자화된 CRaC 컨텍스트 구현을 포함해요.
런타임 훅 등록과 실행
Lambda가 런타임 훅을 실행하는 순서는 등록 순서에 따라 결정돼요. 등록 순서는 코드에서의 import, 정의, 실행 순서를 따라요.
beforeCheckpoint(): 등록의 역순으로 실행돼요.afterRestore(): 등록 순서대로 실행돼요.
등록된 모든 훅이 함수의 코드에 제대로 import되고 포함되도록 하세요. 런타임 훅을 별도 파일이나 모듈에 등록한다면, 그 모듈이 함수의 핸들러 파일에 직접 또는 더 큰 패키지의 일부로 import되도록 해야 해요. 파일이나 모듈이 함수 핸들러에서 import되지 않으면 Lambda가 런타임 훅을 무시해요.
참고 Lambda가 스냅샷을 만들 때 초기화 코드는 최대 15분까지 실행될 수 있어요. 시간 제한은 130초 또는 구성된 함수 타임아웃(최대 900초) 중 더 높은 값이에요.
beforeCheckpoint()런타임 훅은 초기화 코드 시간 제한에 포함돼요. Lambda가 스냅샷을 복원할 때 런타임은 로드되어야 하고afterRestore()런타임 훅은 타임아웃 제한(10초) 안에 완료되어야 해요. 그렇지 않으면 SnapStartTimeoutException이 발생해요.
1단계: 빌드 구성 업데이트하기
빌드 구성에 org.crac 의존성을 추가해요. 다음 예시는 Gradle을 사용해요. 다른 빌드 시스템의 예시는 Apache Maven 문서를 참고하세요.
dependencies {
compile group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.2.1'
# All other project dependecies go here:
# ...
# Then, add the org.crac dependency:
implementation group: 'org.crac', name: 'crac', version: '1.4.0'
}
2단계: Lambda 핸들러 업데이트하기
Lambda 함수 핸들러는 이벤트를 처리하는 함수 코드의 메서드예요. 함수가 호출되면 Lambda가 핸들러 메서드를 실행해요. 함수는 핸들러가 응답을 반환하거나, 종료되거나, 타임아웃될 때까지 실행돼요.
자세한 내용은 Java에서 Lambda 함수 핸들러 정의하기를 참고하세요.
다음 예시 핸들러는 체크포인트 전(beforeCheckpoint())과 복원 후(afterRestore())에 코드를 실행하는 방법을 보여줘요. 이 핸들러는 또한 Resource를 런타임이 관리하는 전역 Context에 등록해요.
참고 Lambda가 스냅샷을 만들 때 초기화 코드는 최대 15분까지 실행될 수 있어요. 시간 제한은 130초 또는 구성된 함수 타임아웃(최대 900초) 중 더 높은 값이에요.
beforeCheckpoint()런타임 훅은 초기화 코드 시간 제한에 포함돼요. Lambda가 스냅샷을 복원할 때 런타임(JVM)은 로드되어야 하고afterRestore()런타임 훅은 타임아웃 제한(10초) 안에 완료되어야 해요. 그렇지 않으면 SnapStartTimeoutException이 발생해요.
...
import org.crac.Resource;
import org.crac.Core;
...
public class CRaCDemo implements RequestStreamHandler, Resource {
public CRaCDemo() {
Core.getGlobalContext().register(this);
}
public String handleRequest(String name, Context context) throws IOException {
System.out.println("Handler execution");
return "Hello " + name;
}
@Override
public void beforeCheckpoint(org.crac.Context<? extends Resource> context)
throws Exception {
System.out.println("Before checkpoint");
}
@Override
public void afterRestore(org.crac.Context<? extends Resource> context)
throws Exception {
System.out.println("After restore");
}
}
Context는 등록된 객체에 대한 WeakReference만 유지해요. Resource가 가비지 컬렉션되면 런타임 훅이 실행되지 않아요. 런타임 훅이 실행되도록 보장하려면 코드가 Resource에 대한 강한 참조(strong reference)를 유지해야 해요.
피해야 할 패턴 두 가지 예시는 다음과 같아요.
예시 — 강한 참조가 없는 객체
Core.getGlobalContext().register( new MyResource() );
예시 — 익명 클래스의 객체
Core.getGlobalContext().register( new Resource() {
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception {
// ...
}
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
// ...
}
} );
대신 강한 참조를 유지하세요. 다음 예시에서 등록된 리소스는 가비지 컬렉션되지 않고 런타임 훅이 일관되게 실행돼요.
예시 — 강한 참조가 있는 객체
Resource myResource = new MyResource();
// This reference must be maintained to prevent the registered resource from being garbage collected
Core.getGlobalContext().register( myResource );