핵심 요약
Spring Boot 5 + GraalVM 25 LTS native image로 JVM에서 절대 안 되던 콜드 스타트 50ms대 진입. AWS Lambda에서 SnapStart 없이 즉시 응답, 메모리 사용량 70MB → 25MB. 단, 빌드 시간 9분, 일부 라이브러리 reflection metadata 수동 등록 필요.
1. 빌드
# pom.xml — native profile
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
mvn -Pnative native:compile
9분 정도 걸린다. CI에 cache 적극 사용.
2. 실측 — Hello World API
| JIT | Native | |
|---|---|---|
| 콜드 스타트 | 2,800ms | 52ms |
| p50 응답 | 4ms | 3ms |
| p99 | 32ms | 5ms |
| RSS | 240MB | 62MB |
3. Reflection — 함정
reflection을 쓰는 라이브러리(예: 일부 ORM 매퍼, JSON 라이브러리)는 빌드 시 모르면 런타임 NPE. Spring Boot 5는 대부분 자동 hint를 등록하지만, 직접 작성한 reflective 코드는 RuntimeHintsRegistrar로 명시.
4. Lambda 배포
FROM public.ecr.aws/lambda/provided:al2023
COPY target/myapp /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/myapp"]
provided runtime + native 바이너리. Lambda 콜드 스타트 80ms 측정.
5. 메모리
Lambda 256MB → 128MB로 줄이고도 동작. 비용 50% 절감. 단, 부하 시 GC 압박이 있으면 192MB가 안정.
6. 빌드 시간 단축
- buildah/Kaniko 빌드 캐시 적극 사용
- PGO(Profile-Guided Optimization)는 효과 크지만 빌드 30% 추가
- 모놀리식 빌드 대신 서비스 단위 native 빌드
7. 어디까지 native?
| 유형 | native 효익 |
|---|---|
| HTTP API | 매우 큼 |
| Batch Job(JIT warmup 이전 종료) | 매우 큼 |
| 장시간 동작 워커 | 중간(JIT가 따라잡음) |
| 대규모 데이터 처리 | JIT가 우세인 경우 많음 |
자주 묻는 질문
Q. JNI/네이티브 라이브러리는? 동적 로드는 빌드 시 명시 필요. 정적 링크 가능하면 더 안전.

댓글 0