Quarkus가 무엇인지 다루기 전에 Quarkus라는 프레임워크가 왜 필요한지에 대한 이야기를 먼저 해야 할 듯 하다.
클라우드의 사용은 나날이 늘어나고 있다. 애플리케이션은 클라우드에서 운영 가능하도록 발전하고 있으며 개발 프로세스 또한 클라우드를 기반으로 혹은 클라우드에서 운영되는 것을 목표로 애플리케이션이 개발되고 있다.
이는 애플리케이션의 현대화를 위한 작업이다. 애플리케이션의 현대화는 클라우드 네이티브(cloud-native) 애플리케이션으로 직결된다.
클라우드 네이티브는 다음의 4가지 특징을 가진다.
- DevOps
- Microservices
- CI/CD
- Container
여기서 오늘 중점적으로 볼 항목은 마이크로서비스(Microservices) 부분이다.
엔터프라이즈 기업들은 그동안 JavaEE의 스펙으로 애플리케이션을 많이 구현하였다. 일반적인 3-티어 구조로 WEB-WAS-DB의 구조로 된 아키텍처에서 최근 마이크로서비스 아키텍처의 도입을 하고 있는 중이다. 따라서 기존 개발자들과 아키텍터들은 JAVA에 이미 익숙해져 있는 상태이고 마이크로서비스도 JAVA를 기반으로 많이 만들고 있다.
JAVA기반의 마이크로서비스를 구현한다면 대부분은 Spring Boot 를 통해서 마이크로서비스를 구현할 것이다. 이미 Spring 은 많이 알려진 프레임워크이고 사용자도 많기 때문에 따로 언급을 할 필요는 없을 것이다. Spring 말고도 최근에는 JAVA 언어를 기반으로 하는 마이크로서비스 프레임워크들이 생겨나고 있다.
기존 엔터프라이즈 애플리케이션들은 JavaEE기반으로 만들어졌다. JavaEE가 이클립스 재단으로 넘어간 후 JakartaEE로 명명되었으며 오라클, IBM 및 레드햇을 포함한 이클립스 재단에서는 최근 클라우드 기반의 엔터프라이즈 애플리케이션을 위한 스펙으로 JakartaEE에서 특징들을 추출한 MicroProfile을 발표했다.

앞에서 언급한 것과 같이 JAVA기반의 마이크로서비스를 구현하기 위한 방법으로 Spring 뿐만 아니라 MicroProfile를 이용할 수가 있다. 개발자의 관점에서는 Spring과 MicroProfile 중에 어느 것을 선택해야 할 것인가를 고민해야 할 수도 있다. 기능적으로는 비슷하고 이를 구현하는 방법이 다르다고 할 수 있을 것이다.
Spring | MicroProfile | |
REST APIs | ||
REST Service | Spring MVC | JAX-RS |
Dependency Injection | Spring IoC & DI | CDI |
API Documentation | Spring REST Docs | MicroProfile Open API |
REST Client | Spring MVC Feign | MicroProfile REST Client |
JSON Binding/Processing | Bring Your Own Library Jackson | JSON-B JSON-P |
Handling 100s of Services | ||
Configuration | Spring Boot Config Spring Cloud Config | MicroProfile Config |
Fault Tolerance | Netflix Hystrix | MicroProfile Fault Tolerance |
Security | Spring Security Spring Cloud Security | EE Security MicroProfile JWT Propagation |
Operation Focus | ||
Health Checks | Spring Boot Actuator | MicroProfile Health Check |
Metrics | Spring Boot Actuator | MicroProfile Metrics |
Distributed Tracing | Spring Cloud Sleuth | MicroProfile Open Tracing |
MicroProfile을 바탕으로 마이크로서비스를 구현하기 위한 프레임워크는 아래와 같이 다양하다. 각 벤더에서 MicroProfile의 지원하는 프레임워크를 만들어서 배포하고 있다.

레드햇에서는 Quarkus를 통해 MicroProfile을 지원하고 있다.
사실, 개발자의 입장에서는 Java기반의 마이크로서비스를 만들기 위해 가장 널리 사용되고 에코시스템도 풍부한 Spring을 사용하는 것이 진입장벽이 낮다. 이제 신생인 Quarkus를 사용하여 마이크로서비스를 만들기에는 정보와 에코시스템이 부족할 수가 있다. 그럼에도 불구하고 클라우드 네이티브 마이크로서비스를 구현하기 위해서 Quarkus를 선택하는 것이 왜 더 나은 선택인지 알아보도록 한다.
QUARKUS
Quarkus는 레드햇의 주도로 Java 가상 머신(JVM) 및 네이티브 컴파일을 위해 만들어진 풀스택, 쿠버네티스 네이티브 Java 프레임워크로, 특히 컨테이너에 Java를 최적화하여 이를 서버리스(serverless), 클라우드 및 쿠버네티스 환경을 지원하는 효과적인 플랫폼이다.
Quarkus는 Eclipse MicroProfile 및 Spring, Apache Kafka, RESTEasy(JAX-RS), Hibernate ORM(JPA), Spring, Infinispan, Camel 등과 같이 널리 사용되는 Java 표준, 프레임워크 및 라이브러리와 연동되도록 설계되었다.
Quarkus의 종속성 주입은 CDI(Contexts and Dependency Injection)를 기반으로 하며, 기능을 확장 프레임워크를 애플리케이션으로 설정, 부팅 및 통합하기 위한 확장 프레임워크를 포함합니다.
또한 GraalVM(Java 및 JavaScript를 포함한 여러 언어로 작성한 애플리케이션을 실행하기 위한 범용 가상 머신)에 정확한 정보를 제공하여 애플리케이션의 네이티브 컴파일을 지원한다.
홈페이지는 quarkus.io 이며, 해당 홈페이지의 첫 화면에서 다음과 같이 Quarkus의 특징이 잘 나열되어 있다.

위의 그림에서 보듯이 Quarkus의 여러가지 장점들이 있는데 이 글에서는 첫번째 장점인 “Container First”에 집중해 보도록 한다.
Container-First
Quarkus의 컨테이너 우선 정책은 다음 4가지의 특징을 가진다.
- 빌드 타임 메타데이터 처리
- 리플렉션 사용 감소
- Graal/SubstrateVM에 대한 최고 수준의 지원
- 기본 이미지 사전 부팅
빌드 타임 메타데이터 처리
일반적으로 Java의 빌드타임에서는 .class 라는 바이트코드를 만드는 작업을 한다. 실행시간에는 이 바이트코드를 읽어 configuration parsing, classpath scanning, feature toggle based on classloading 같은 일들을 처리 한 후 애플리케이션을 실행하게 된다.

Quarkus는 이러한 실행시간에 하는 일들을 빌드타임에서 미리 수행함으로써 일반적인 Java 애플리케이션보다 실행 시작시간을 줄일 수가 있다. 실행 시작시간을 줄인다는 것은 애플리케이션이 시작하기 까지의 대기시간이 줄어든다는 말이며, 이는 컨테이너로 서비스를 수행 시, 보다 빠르게 서비스를 시작할 수 있다는 의미이다.
리플렉션 사용 감소
Java의 리플렉션은 객체를 통해 클래스의 정보를 분석해 내는 기법이다. 오브젝트의 이름으로 애플리케이션이 사용자 정의 클래스를 사용할 수 있는 장점이 있으나 성능 오버헤드 되는 단점이 있다.
Class c = Data.class;
//Class c = Class.forName("클래스이름");
Method[] m = c.getMethods();
Field[] f = c.getFields();
Constructor[] cs = c.getConstructors();
Class[] inter = c.getInterfaces();
Class superClass = c.getSuperclass();
Quakrus는 클래스 경로에서 사용 가능한 애플리케이션 코드와 클래스를 분석하고 리플렉션 호출을 일반 호출로 대체한다. 결과적으로 애플리케이션에는 직접 호출만 포함되며 직접 호출되지 않는 모든 필드, 메서드 및 클래스는 의도적으로 제거된다.
Graal/SubstrateVM에 대한 최고 수준의 지원
GraalVM은 AOT 컴파일러를 지원한다. JIT 컴파일러는 바이트코드로 이루어진 .class를 인터프리터하여 기계어로 번역하여 애플리케이션을 실행하는 반면, AOT 컴파일러는 바이트코드 없이 소스코드를 기계어로 변경한다.

AOT 컴파일러는 기계어로 직접 바꾸기 때문에 시작시간이 빠르고 메모리를 적게 차지하는 반면, JIT 컴파일러가 가지는 높은 처리량과 최대 대기시간 감소라는 이점은 약하다. 하지만 최근 애플리케이션이 클라우드에서 컨테이너로 배포되고 애플리케이션이 빨리 시작되고 작게 유지되는 것이 중요한 시점에서 AOT 컴파일러는 클라우드에서 JAVA를 위한 최고의 수단이 아닐까 생각한다.
GraalVM의 native-image를 사용하면 이러한 AOT 컴파일러를 이용하여 애플리케이션 시작시간이 매우 짧고 메모리 사용량도 매우 적은 JVM이 없이도 실행이 가능한 파일로 배포되는 것이 가능하다. 이는 AOT 컴파일러가 JIT 컴파일러가 하는 여러가지 단계들이 필요가 없기 때문이다.
JIT | AOT |
•운영 체제는 JVM 실행 파일을 로드합니다. •VM은 파일 시스템에서 클래스를 로드합니다. •바이트코드가 확인됨 •바이트코드 해석 시작 •정적 이니셜라이저 실행 •첫 번째 계층 컴파일(C1) •수집된 프로파일링 지표 •… (몇 시간 후) •2계층 컴파일(C2/ Graal 컴파일러) •마지막으로 최적화된 머신 코드로 실행 | •운영 체제는 준비된 힙으로 실행 파일을 로드합니다. •최적화된 기계 코드로 애플리케이션이 즉시 시작됩니다. |
AOT 컴파일러의 큰 장점은 JIT 컴파일러에 비해서 프로그램 시작시간이 짧고 메모리 사용률이 적다는 것이다.

Quarkus는 이러한 GraalVM을 기본 지원하도록 설계되었으며 이러한 특징은 클라우드 네이티브 애플리케이션을 구성하는데 매우 큰 이점으로 다가온다. 또한 AOT컴파일러를 이용한 native-image로 배포하게 되면 Java 애플리케이션이지만, 요청이 있을 때만 서비스를 하는 serverless 를 위한 애플리케이션으로 손색이 없다.
기본 이미지 사전 부팅
사전 부팅(pre-boot)이라 함은 미리 로드 하는 것이다. Quarkus extensions 은 프레임워크 또는 기술을 Quarkus 애플리케이션에 구성, 부팅 및 통합함으써 애플리케이션이 기본적으로 컴파일할 수 있도록 GraalVM에 올바른 정보를 제공하는 어려운 작업을 모두 수행한다.
Quarkus에서는 extensions을 통하여 많은 라이브러리를 기본 이미지에 re-boot 할 수가 있다.

Performance
Quarkus를 언급할 때 가장 중요한 요소가 성능측면이다. 위의 Container-First 항목에서 보듯이 빌드 타임 프로세싱과 GraalVM의 지원은 Quarkus를 이용한 애플리케이션이 최고의 퍼포먼스를 낼 수 있는 충분조건을 제공한다.

위의 그림은 일반 클라우드 네이티브 애플리케이션, Quarkus를 사용, Quarkus와 GraalVM을 사용 했을 때의 시작시간 및 메모리 사용량을 나타낸 것이다.
BOOT + First Response Time을 보면 기존 애플리케이션에 비해서 Quarkus를 사용한 애플리케이션이 4.5 배가 빠른 것을 알 수 있고, Quarkus와 GraalVM의 native를 사용한 애플리케이션은 Quarks만 사용한 애플리케이션보다 60배가 빠른 것을 알 수 있다.
결과적으로 기존 애플리케이션과 Quarkus+GraalVM의 native 애플리케이션은 240배 만큼의 차이가 난다. WoW!! 믿을 수 없는 수치이지만, 공식적인 수치이다.
시작하세요
Java로 만든 서비스를 하고자 한다면, 이제 마이크로서비스 아키텍처로 애플리케이션을 시작하려 한다면,
이전의 시작시간이 느리고 메모리를 많이 차지하는 Java를 벗어나 빠른 시작시간과 적은 메모리를 차지하는 Java 기반의 마이크로서비스를 Quarkus와 함께 시작하길 바라며 이 글을 마무리 한다.
감사합니다.
-본 글의 내용, 입장, 예측은 개인적인 것이며 개인이 소속된 회사를 공식적으로 대변하지 않습니다.-
참조
https://quarkus.io/container-first/
https://www.eclipse.org/community/eclipse_newsletter/2019/september/microprofile.php
https://www.redhat.com/ko/topics/cloud-native-apps/what-is-quarkus
https://www.infoq.com/articles/native-java-graalvm/
https://www.graalvm.org/22.1/docs/introduction/
https://twitter.com/thomaswue/status/1145603781108928513