개발자 / 클라우드

"클라우드 네이티브로 한 걸음 더 가까이" 다가간 자바 프레임워크 8종

Peter Wayner  | InfoWorld 2022.06.30
자바 프로그래밍 언어는 처음 등장한 후 30년 가까운 시간 동안 임베디드 칩부터 대규모 서버 팜에 이르기까지 도처에서 활발히 사용되고 있다. 자바가 가진 견고한 가상머신과 방대한 라이브러리의 조합은 어디에서나 실행되는 코드를 쓰기 위한 풍성한 생태계를 구축했다.
 
그러나 자바는 수천에서 수백만 명에 이르는 사용자 간 연결을 다뤄야 하는 서버에서는 유독 고전했다. 초기 자바 툴은 모든 사용자를 대상으로 비즈니스 로직을 실행하는 서버 측 애플리케이션을 만드는 최적의 툴이었다. J2EE, 하이버네이트(Hibernate), 스프링(Spring)과 같은 자바 프레임워크와 기본적인 자바 서블릿 모델은 강력한 웹 애플리케이션을 비교적 쉽게 만들 수 있게 해주는 요소였다.
 
이 기술은 자바스크립트와 Node.js가 등장하기 전까지 번성했다. Node.js는 많은 관심을 끌었고 개발자는 자바스크립트 런타임 환경으로 이동하기 시작했다. 이유는 두 가지다. 첫째, 서버와 브라우저 클라이언트에서 동일한 코드를 실행할 수 있다는 점이 개발자의 마음을 샀고, 둘째, Node.js 서버가 리액티브 모델 덕분에 대체로 처리량이 훨씬 더 빨랐다.
 
ⓒ Getty Images Bank

자바 생태계도 경쟁하기 위해 환경에 적응했다. 처음 일부 개발자는 자바를 자바스크립트로 변환하는 구글 웹 툴킷과 같은 툴을 채택했다. 이후에는 서버에서 자바의 속도를 높이기 위해 노력했다. 초기 서버용 자바 프레임워크에는 수신되는 각 요청에 자체 쓰레드가 부여된다는 제약이 하나 있었다. 들어오고 나가는 데이터를 확실히 정리하기 위한 방법이었지만 부하가 컸다. 하나의 쓰레드를 만드는 데 수천 바이트의 오버헤드가 발생하고, 그 때문에 각 서버가 처리할 수 있는 사용자 수가 제한될 수 있었다. Node.js는 다른 모델로 이 오버헤드 없이 훨씬 더 많은 사용자를 처리하다.
 
더 최근에는 자바 개발자가 Node.js 의 혁신을 자바 스택, 특히 클라우드 네이티브 자바 프레임워크로 가져오기도 했다. 이러한 프레임워크는 Node.js의 접근 방식을 모방하며 클라우드 머신에서 실행되고 신속하게 시작 및 중지할 수 있는 가벼운 함수를 지원한다. 가능한 가장 간소한 서버 인스턴스에서 빠른 구현을 지원하기 위해 부가적인 라이브러리의 필요성을 없앴다. 클라우드 네이티브 자바 프레임워크는 독립적으로 설치와 재시작이 가능한 수많은 마이크로서비스를 지원한다. 일반적으로 가능한 가장 빠른 빌드와 설치를 위해 도커(Docker) 또는 팟맨(Podman)과 같은 컨테이너 형태로 제공된다. 
 
클라우드 네이티브 환경을 찾는 현대 자바 개발자가 선택할 수 있는 옵션은 많다. 이상적인 클라우드 네이티브 자바 프레임워크는 자바 플랫폼과 서드파티 라이브러리의 깊이 있는 경험을 활용하는 동시에 클라우드에서 더 빠르고 가볍게 실행되도록 이러한 요소를 수정하기도 한다. 클라우드 네이티브 개발 및 배포를 위해 새롭게 만들어진 8개 자바 프레임워크를 소개한다.
 

마이크로넛(Micronaut)

마이크로넛이 만들어진 목적은 스프링, 그레일즈와 같은 전통적인 자바 프레임워크에서 유연한 구성 및 종속성 주입과 같은 좋은 부분을 취하고, 마이크로서비스 개발 측면에서 불리한 높은 메모리 사용량, 느린 시작 속도와 같은 부분을 없애는 것이다. 마이크로넛 개발진은 구식 프레임워크에 사용되는 메모리 소비량이 큰 리플렉션 없이 종속성 주입에 대해 충분한 정보를 제공하는 주석을 세심하게 설계했다. 마이크로넛 구성의 많은 부분은 컴파일 시에 수행되므로 코드는 그만큼 더 빠르고 가볍게 실행된다.
 
프레임워크는 다양한 JVM 기반 언어를 지원하며(현재 자바, 코틀린, 그루비) 이러한 언어를 다양한 클라우드에 걸쳐 실행한다. 사전 정의된 구성 파일은 모든 주요 클라우드에서 서버 또는 서버리스 함수 배포를 간소화해주며 모든 주요 데이터베이스 연결을 위한 잘 정리된 설명서도 있다.
 
마이크로넛 개발자는 효과적인 개발 팀워크를 지원하는 데도 공을 들이고 있다. HttpClient 구현에는 마이크로넛에서 나가거나 더 많은 작업을 추가하지 않으면서 단위 테스트를 간단히 만들 수 있게 해주는 프로젝트가 함께 제공된다. 이러한 테스트는 동적 프레임워크에 필요한 테스트에 비해 더 간편하고 포괄적인 경우가 많다. 이 역시 컴파일 시에 수행되는 작업 덕분이다.
 
마이크로넛의 용도는 클라우드 함수를 사용한 애플리케이션 개발이 전부가 아니다. 이 프레임워크는 전통적인 역할과 일부 데스크톱 애플리케이션도 지원한다. 그랄VM(GraalVM)과 긴밀하게 통합되므로 마이크로넛을 사용해 네이티브 애플리케이션을 생성할 수 있다.
 

쿼커스(Quarkus)

이미 잘 알려진 명령형 리액티브 코드를 사용하고자 하는 개발자는 쿼커스를 선택할 수 있다. 쿼커스 팀은 클라우드 네이티브 개발의 가장 일반적인 사용 사례를 예측한 후 이러한 사용 사례를 지원하는 예제를 사용해서 구성이 거의 없는 프레임워크를 구축했다. 결과적으로 손쉽게 컨테이너에 넣고 쿠버네티스 클러스터에 배포할 수 있는 프레임워크가 만들어졌다.
 
개발 팀은 쿠버네티스 클러스터가 빠르게 확장이 가능하도록 부팅 시간을 단축하는 데 특히 주력했다. 호출될 때까지 비활성 상태로 둘 수 있으므로 산발적으로 실행되는 함수에 이상적이다.
 
프로젝트의 목표 중 하나는 자바 커뮤니티에서 보편적으로 사용되는 기존의 많은 표준과 라이브러리를 수용하고 확장하는 것이다. 예를 들어 JAX-RS 주석은 레스트(REST) 엔드포인트를 정의한다. 구성은 이클립스 마이크로프로파일(Eclipse MicroProfile)부터 시작된다. 또한 쿼커스의 개발 팀은 50개 이상의 표준 라이브러리를 통합했으므로 특정 사례를 다루다 보면 아마 설계 패턴을 알아챌 수 있을 것이다.
 
기본적인 쿼커스 프레임워크를 다양한 서비스에 사용할 수 있다. 쿼커스 개발진은 쿼커스 2.8부터 레스트이지 리액티브(RESTeasy Reactive) 모델을 장려하고 있다. 새 프로젝트를 시작할 경우 표준 옵션이지만 꼭 사용할 필요는 없다. 레스트이지 리액티브는 더 간소한 논블로킹 구조와 패턴을 제공한다. 각 요청에 하나의 쓰레드를 할당하는 대신 일련의 논블로킹 쓰레드가 모든 I/O를 처리하고 필요할 때 코드를 호출한다.
 
쿼커스는 다양한 배포 옵션도 채택하고 있다. “컨테이너 우선”을 내세우긴 하지만 베어 메탈에서도 실행이 가능하다. 또한 펀지(Fungy)라는 내장 구성 옵션이 AWS 람다, 애저 펑션, K네이티브(Knative) 등에서 수락되는 함수를 간편히 생성할 수 있게 해준다.
 

스프링 클라우드 펑션(Spring Cloud Functions)

스프링 프레임워크는 약 20년 동안 많은 프로젝트의 기반이 된 만큼 자바 개발자에게 매우 친숙하다. 스프링 개발자는 클라우드 배포를 비롯한 다른 역할에 더 잘 맞는 새 버전을 만들기로 결정했다. 스프링 클라우드 펑션의 함수는 웹 서비스, 스트림 처리, 백그라운드 작업과 같은 다양한 작업에 손쉽게 재배포가 가능하도록 만들어진다.

스프링 클라우드 펑션 프레임워크는 스프링이 개척한 철학적 전통의 상당수를 그대로 계승한다. 이 프레임워크의 클라우드 함수는 리액티브 또는 명령형 스타일과 둘의 혼합을 지원한다.
 
다양한 옵션을 지원하는 것이 이 프로젝트의 큰 목표다. 이 프레임워크를 도입한 사람들은 AWS 람다, 마이크로소프트 애저, 아파치 오픈위스크, 구글 클라우드 플랫폼 및 그 외의 여러 일반적인 클라우드 함수 환경에 스프링 클라우드 펑션 함수를 집어넣는다. 또한 아파치 카프카, 솔레스(Solace), 래빗MQ(RabbitMQ)와 같은 주요 스트리밍 프레임워크와 독립적인 옵션인 스프링 클라우드 스트림(Spring Cloud Stream)용으로 사용하는 사람들도 있다. 패키징과 배포의 많은 부분이 자동화되므로 함수 자체를 개발하는 데 집중할 수 있다.
 
또한 스프링 클라우드 펑션 개발 팀은 클라우드 배포의 일반적인 위험 요소와 난관을 해결하는 데 많은 공을 들였다. 스프링 클라우드 스키퍼(Skipper)를 사용하면 여러 클라우드 사이에서 배포를 효율적으로 조직할 수 있다. 스프링 클라우드 슬루스(Sleuth)는 데이터 흐름을 추적해 디버깅에 도움을 준다. 스프링 클라우드 시큐리티는 애플리케이션 보안을 위한 많은 부분을 관리해서 적절한 사람만 함수를 실행할 수 있도록 한다. 하위 프로젝트만 해도 수십 개에 이른다.
 
이 프로젝트는 다양한 플랫폼을 통한 비즈니스 애플리케이션 배포의 기반으로도 효과적이다. 애플리케이션 로직이 클라우드 펑션 POJO 안에 캡슐화되면 수십 가지의 다른 역할에서 편리하게 사용할 수 있다.
 

버텍스(Vert.x)

버텍스의 목표는 이벤트 루프를 간소화하고 데이터베이스와의 연결을 최적화해서 매우 빠른 프레임워크를 만드는 것이다. 버텍스에는 Node.js와 마찬가지로 하나의 이벤트 루프가 있어서 이벤트가 도착함에 따라 여러 연결을 효과적으로 조직할 수 있다. 또한 자바의 스레딩 모델을 활용해서 하나의 풀에 있는 여러 쓰레드로 이벤트를 처리할 수 있다. 이는 가용한 경우 여러 코어에서 실행될 수 있다.
 
또한 이 구조는 이벤트 스트림을 처리하기 위한 파이프라인 생성을 단순화한다. 계층화된 콜백으로 인한 혼잡한 코드를 피하기 위해 프로미스(promise), 퓨처(future)와 같은 구조체를 사용한다. 이 비동기 옵션은 이벤트가 이벤트 버스를 따라 이동하는 과정에서 간단한 메서드 호출 체인으로 채워지는, 깔끔하고 읽기 편한 코드를 생성하는 데 도움이 된다.
 
버텍스 개발 팀은 비전을 독단적으로 내세우지는 않는다. 이들이 자주 하는 말은 버텍스는 프레임워크가 아니라 툴킷이라는 것이다. 코드는 모듈형이므로 사용할 기능을 선택해서 애플리케이션에 맞게 조립할 수 있다. 리액티브보다 명령형 구조를 선호하는 프로그래머라면 코틀린의 코루틴 지원을 활용할 수 있다.
 
이 프로젝트는 이클립스 생태계의 일부다. 다양한 버전과 옵션 덕분에 자유도가 높다. 예를 들어 버텍스 애플리케이션 생성기는 템플릿 엔진 또는 API 지원과 같은 수십 가지의 잠재적인 종속 항목과 함께 자바 또는 코틀린 코드를 생성한다.
 

이클립스 마이크로프로파일(Eclipse MicroProfile)

이클립스 팀은 더 작은 마이크로서비스 환경에서 실행되도록 자카르타(Jakarta) EE를 개조하기 위한 방편으로 마이크로프로파일 프로젝트를 만들었다. 플랫폼의 큰 오버헤드를 없애면서 많은 마이크로서비스 아키텍처에서 사실상 표준으로 사용되는 라이브러리를 모았다.
 
이 접근 방법은 더 크고 오래된 자바 EE 또는 자카르타 EE 프로젝트에서 코드를 이전하고자 하는 개발자에게 가장 매력적이다. 구성과 아키텍처의 대부분은 그대로 유지된다. 많은 경우 조정은 간단하다. 그러나 이 설계는 더 가벼운 무게, 더 빠른 코드를 생성하는 더 간소화된 코드로의 의사 결정을 촉진한다. 일부 개발자는 마이크로프로파일을 더 현대적인 클라우드 네이티브 프레임워크로 가기 위한 발판으로 사용한다.
 

드롭위저드(Dropwizard)

오래되고 충분히 테스트된 모듈을 더 선호하는 개발자에게는 드롭위저드가 좋다. 드롭위저드의 개발 팀은 처음부터 안정적, 성숙함 등의 단어를 강조해왔다. 이들은 하이버네이트와 같은 데이터베이스 연결을 위한 모듈을 모아 양식 및 기타 표준 웹 애플리케이션 구성요소를 위한 프레임워크를 만들었다. 또한 드롭위저드는 구성 및 로깅과 같은 런타임 유지보수 프로세스와 종속성 주입을 간소화한다.
 
드롭위저드는 기존 애플리케이션을 수정하고 확장하는 팀에게 적합하다. 오래된 성숙한 접근 방식을 기반으로 하므로 그러한 방식과 호환되는 구조를 갖고 있다.
 

클라우드 플랫폼을 위한 첫 프레임워크

복잡하거나 장황한 것이 필요 없을 때도 있다. 모든 클라우드는 간단한 함수 작성을 시작할 경우 적합한 기초적인 예제를 제공한다. 주로 매우 간단한 의사 결정을 지원하고 개발자가 빠르게 시작하도록 돕는 것을 목표로 한다.
 
예를 들어 구글 클라우드 플랫폼의 개발 팀은 자체 서비스형 함수(FaaS)에서 실행되는 자바 함수를 위한 기본 프레임워크를 오픈소스로 공개했다. 이를 사용하여 만들어진 코드는 GCP의 표준 트리거와 신속하게 통합되며 로컬 머신에서도 원활하게 실행이 가능하다.
 
마이크로소프트도 자바용 프레임워크를 오픈소스화했다. 이 모델에는 JSON 데이터를 자바 POJO로 변환하는 라이브러리와 같은 데이터 전송을 간소화하기 위한 여러 루틴이 포함돼 있다. 함수 트리거가 호출과 함께 메타데이터를 제공하는 경우 프레임워크에서 이를 직접 처리한다.
 
두 가지 프레임워크 모두 하나의 함수가 있는 하나의 클래스만으로 많은 간단한 작업을 수행할 수 있게 해준다. 더 복잡한 프로젝트에서는 이 기본 툴에 위에서 설명한 다른 프레임워크를 병합할 수 있을 것이다. 두 프레임워크는 출발점이라고 할 수 있지만, 그것만으로 충분한 경우도 있다.
editor@itworld.co.kr 

회사명 : 한국IDG | 제호: ITWorld | 주소 : 서울시 중구 세종대로 23, 4층 우)04512
| 등록번호 : 서울 아00743 등록발행일자 : 2009년 01월 19일

발행인 : 박형미 | 편집인 : 박재곤 | 청소년보호책임자 : 한정규
| 사업자 등록번호 : 214-87-22467 Tel : 02-558-6950

Copyright © 2024 International Data Group. All rights reserved.