Quarkus : Java 에서 네이티브 바이너리를 생성해주는 컨테이너에 최적화된 프레임워크
Kubernetes 와 마이크로서비스 아키텍처의 확산으로 애플리케이션을 컨테이너에서 운영하는 것이 일반화되고 있습니다.
이러한 컨테이너 기반의 애플리케이션 개발에는 Golang이나 Ruby 등 가벼우며 기동 시간(Boot time)이 짧고 메모리 사용량이 적은 언어가 사용되는 경우가 많으며, 반면에 시작 시간이 느리고 메모리 사용량이 큰 Java는 외면 당해 왔습니다.
하지만 Java 에코 시스템은 20 년 넘게 계속되고 있으며, 현재에도 많은 개발자들에게 인기있는 언어 중 하나 입니다.
컨테이너 환경에서 자바가 적응 하지 못하는 부분인 느린 부팅 속도와 많은 메모리 사용에 대한 부분에 대한 해결책을 알아 봅니다.
기존 Java 와 Quarkus 와의 성능 비교
(source : Supersonic, Subatomic Java by Alex Soto, Software Engineer en Red Hat)
Quarkus는 “Supersonic Subatomic Java (초음속 · 원자보다 작은 Java)”라는 캐치 프레이즈를 가진 것처럼, GraalVM를 사용하여 만든 Linux의 Native 바이너리를 컨테이너에서 시작하여 Java의 시작 시간을 획기적으로 단축하고 있습니다.
Java 개발자가 지금까지 쌓아온 지식과 기술을 활용하면서 Kubernetes 네이티브 컨테이너 어플리케이션을 Java를 사용하여 배포하기 위해 등장한 것이 바로 ‘Quarkus “입니다.
컨테이너와 Kubernetes 에 최적화된 Java
첫 번째로 성능 측면에서 자바는 장기간 실행되는 프로세스 처리에 최적화 되어서 JVM 이 HotSpot 엔진을 워밍업하고 정상적인 처리에 도달하는데 많은 시간이 필요합니다.
만약 애플리케이션을 신속하게 시작해야 하는 경우라면 자바가 아닌 다른 언어로 애플리케이션을 개발해야 할 것입니다.
하지만 Quarkus 프레임워크를 이용하여 Java 애플리케이션을 Native 로 변환하여 실행하면 몇 밀리 초 만에 애플리케이션이 실행되는 것을 확인할 수 있습니다.
이 부분이 엔터프라이즈 자바 ( Enterprise Java) 에서 새로운 게임 체이저이며, 우리가 Quarkus 에 관심을 가질 수 뿐이 없는 첫 번째 이유입니다.
두 번째는 메모리 부분으로 자바 애플리케이션은 Java EE 서버에 배포되거나 Spring Boot 등으로 대표되는 fat jar를 이용하는 방법을 사용하고 있습니다.
이러한 경우에 Java VM 과 라이브러리와 응용 프로그램에서 최소 130MB 정도이며, 실제로는 200 MB 을 넘습니다.
getting-started 예제를 native 컴파일 할 때 생성되는 싱글 바이너리 크기는 20MB 정도입니다.
Quarkus 는
Red Hat은 GraalVM 와 OpenJDK HotSpot 용으로 개발 된 Kubernetes 기본 Java 프레임 워크 인 Quarkus 을 출시하였습니다..
반응 형 (reactive)와 명령형 (imperative)를 통합 한 프로그래밍 모델을 제공하여 Java를 Kubernetes와 서버없는 환경(Serverless) 에서 선두 플랫폼으로하는 것을 목표로 합니다.
Quarkus는 Eclipse MicroProfile 과 Vert.x 와 같은 Java 개발자가 사용하는 일련의 라이브러리를 활용하여 전체 스택 프레임 워크를 제공합니다.
Quarkus 의존성 주입은 CDI를 기반으로하며, JPA / Hibernate JAX-RS / RESTEasy 등을 이용할 수 있습니다.
또한 Quarkus는 타사 프레임 워크 개발자가 사용할 수있는 확장 프레임 워크가 포함되어 있으며, 이 확장 프레임 워크는 GraalVM 네이티브 바이너리로 컴파일하는 것이 가능합니다.
RedHat에 따르면, Quarkus 컨테이너 및 Kubernetes에서 마이크로 서비스의 자동 스케일 업 / 다운을 실현하여 기동 시간이 짧아야 하는 마이크로 서비스 아키텍처 운영환경에 적합니다.
또한 컨테이너 밀도의 최적화하여 낮은 메모리 사용량, 애플리케이션 및 컨테이너 이미지의 풋프린트를 낮게 하여 높은 런타임 효율을 실현합니다.
특징
지금까지 Java 어플리케이션은 JavaVM의 시작 시간 오버 헤드 등이 걸리기 때문에 경량 컨테이너 환경을 충분히 살리는 것이 어렵다고 생각했습니다.
그러나 Quarkus는 GraalVM을 사용하여 네이티브의 바이너리를 작성하여 빠르게 애플리케이션을 시작할 수 있도록 하는 프레임워크입니다.
Quarkus를 간단하게 설명하면 Java 소스 코드를 GraalVM 을 이용하여 Linux의 Native 바이너리를 만들고 Linux 바이너리를 컨테이너에서 시작하여 지금까지 Java 의 가장 큰 단점이였던 시작 시간을 대폭 단축 할 수 있습니다.
이 바이너리는 표준 Java VM과 다른 VM 구현으로 Substrate VM이라는 것이 포함되어 있으며, 동작에 별도 Java VM이 설치되어있을 필요 없습니다.
바이너리의 크기 외에도 런타임 시작 속도, CPU 사용량, 메모리 사용량 등을 Java VM에 비교하면 대부분의 경우 몇 배 개선된 것을 확인할 수 있습니다.
Red Hat의 테스트에서는 간단한 데모 애플리케이션이 0.008 초에서 시작한 것으로 소개되어 있습니다.
고려사항
- 얼마되지 않은 오픈소스 프로젝트로 아직 운영 환경에 적용하기는 어렵습니다.
- GraalVM를 사용하여 Linux의 Native 바이너리를 작성합니다. Maven 명령을 실행하고 완료 될 때까지 간단한 애플리케이션의 경우에도 빌드하는 시간이 ‘9 분’정도의 소요됩니다.
정리하자면
Quarkus는 Java 애플리케이션 코드에서 네이티브 바이너리를 생성하고 컨테이너화함으로써 컨테이너와 Kubernetes 환경에 최적화 된 빠르게 시작하고 메모리 소비량도 적은 애플리케이션 실행 파일을 만들수 있는 것입니다.
클라우드 고유의 Enterprise Java를 한 차원 높은 수준으로 끌어 올렸으며, 특히 애플리케이션 시작 시간과 관련해서는 이전에는 불가능했던 시나리오를 지원합니다.
References & Related Links
- https://quarkus.io/
- Introducing Quarkus: a next-generation Kubernetes native Java framework – https://developers.redhat.com/blog/2019/03/07/quarkus-next-generation-kubernetes-native-java-framework/
- Quarkus: Why compile to native? – https://developers.redhat.com/blog/2019/03/29/quarkus-why-compile-to-native/
- Quarkus : CONTAINER FIRST – https://quarkus.io/vision/container-first
- QUARKUS – GET STARTED – https://quarkus.io/get-started/