스프링 네이티브를 스프링 부트 마이크로서비스에 통합하는 방법
본문 바로가기
코딩(Coding)

스프링 네이티브를 스프링 부트 마이크로서비스에 통합하는 방법

by Emily Blunt 2022. 4. 28.
반응형

스프링 네이티브를 스프링 부트 마이크로서비스에 통합하는 방법

 

Spring Native: Spring Boot를 날게 하는 날개

Pixabay로부터 입수된 finix8님의 이미지 배경

웹 및 마이크로서비스 개발 분야에서 엄청난 인기를 누리고 있음에도 불구하고 Spring Boot에는 한계가 있습니다. 가장 눈에 띄는 것은 긴 시작 시간과 높은 메모리 소비입니다. 근본 원인은 Spring이 리플렉션에 의존하여 클래스, 인터페이스, 필드 및 메소드를 검사하는 방법에 있습니다. 실행 시간. 런타임에 리플렉션을 사용하지 않고 동일한 생산성을 가질 수 있습니까?

예! Spring Native에 답이 있습니다!

이 이야기에서는 고객을 관리하기 위한 간단한 CRUD 애플리케이션인 customer-service라는 Spring Boot 마이크로서비스에 Spring Native를 통합하는 방법을 탐구할 것입니다. 우리는 두 개의 고객 서비스 앱을 가질 것입니다. 하나는 customer-service라는 바닐라 Spring Boot 앱이고 다른 하나는 customer-service-native인 Spring Native가 내장된 Spring Boot 앱입니다. 성능 향상 Spring Native는 Spring Boot에 제공합니다.

아래에서 고객 서비스와 고객 서비스 네이티브 간의 시작 시간 비교에 대한 간략한 정보를 제공합니다.

기본 Spring Boot 앱을 위한 초고속 시작! 이 작업을 수행하는 방법을 알아보려면 계속 읽으십시오.

Spring Native는 빌드 시 GraalVM 네이티브 이미지 컴파일러를 사용하여 Spring 애플리케이션을 네이티브 실행 파일로 컴파일합니다. JVM과 비교하여 GraalVM 기본 이미지는 다양한 유형의 워크로드에 대해 더 저렴하고 지속 가능한 호스팅을 가능하게 합니다. GraalVM 기본 이미지를 사용하면 다음과 같은 주요 이점이 있습니다.

  • 즉시 시작
  • 즉각적인 최고 성능
  • 메모리 소비 감소

GraalVM은 마이크로서비스에 이상적인 애플리케이션 성능과 효율성을 크게 개선하는 고성능 클라우드 네이티브 다중 언어 런타임입니다. Oracle Labs에서 개발한 GraalVM은 JVM 기반 언어의 성능을 네이티브 언어의 성능과 일치하도록 개선하는 것을 목표로 합니다. 또한 GraalVM 네이티브 이미지 기술로 미리 컴파일(AOT)하여 JVM 기반 애플리케이션의 시작 시간을 줄이는 것을 목표로 합니다.

Native Image는 Java 코드를 미리 컴파일하는 혁신적인 기술입니다. (AOT) 네이티브 이미지라고 하는 독립 실행형 바이너리 실행 파일로 변환합니다. AOT 컴파일러는 빌드 시간 동안 정적 분석, 사용하지 않는 코드 제거, 고정 클래스 경로 생성 등과 같은 시작 시간을 줄이는 여러 작업을 실행합니다. 네이티브 이미지 빌더, native-image는 JDK의 클래스를 포함하여 애플리케이션의 모든 클래스와 해당 종속성을 처리하는 유틸리티입니다. 이 데이터를 정적으로 분석하여 애플리케이션 실행 중에 연결할 수 있는 클래스와 메서드를 결정합니다. 그럼 미리 도달 가능한 코드와 데이터를 특정 운영 체제 및 아키텍처용 기본 실행 파일로 컴파일합니다.

AOT 컴파일러의 주요 단점은 빌드 시간이 길다는 것입니다. AOT 엔진은 최적화된 애플리케이션 컨텍스트와 우리 애플리케이션을 위해 특별히 제작된 Spring 팩토리(Spring Boot 뒤에 있는 플러그인 시스템)를 생성하기 위해 빌드 시 조건을 평가합니다. 실제로 이는 다음을 의미합니다.

  • 런타임에 실행할 Spring 인프라가 적습니다.
  • 런타임에 평가할 조건이 적습니다.
  • 프로그래밍 방식의 빈 등록이 사용되므로 반사가 적습니다.

Spring Native를 Spring Boot 마이크로 서비스에 통합하는 방법을 보여주기 위해 아래 단계에 따라 성능 향상을 경험함으로써 customer-service라는 데모 Spring Boot 서비스를 기본 Spring Boot 서비스인 customer-service-native로 변환할 것입니다. 스프링 네이티브에 의해.

1단계: GraalVM 및 기본 이미지 도구 설치

GraalVM과 기본 이미지를 모두 설치하려면 GraalVM 시작에 대한 지침을 참조하세요. Windows 사용자의 경우 Windows 10 SDK와 함께 Visual Studio를 설치하는 몇 가지 추가 단계가 있습니다. 이러한 단계를 놓치지 않도록 하십시오. 자세한 내용은 Windows 10에서 GraalVM 및 기본 이미지를 사용하는 스토리에서 찾을 수 있습니다. Windows에서 native-image 도구는 Visual Studio의 x64 기본 도구 명령 프롬프트에서 실행될 때만 작동합니다.

2단계: pom.xml의 변경 사항

Spring Native의 목표는 기존 또는 새로운 Spring Boot 애플리케이션을 기본 실행 파일로 컴파일하는 것을 지원하는 것입니다. 변하지 않은. 이것이 핵심 포인트입니다! Spring Native를 Spring Boot 마이크로서비스에 도입할 때 코드 변경은 예상하지 않습니다. pom.xml과 같은 빌드 파일 변경 또는 기본 힌트와 관련된 모든 구성 변경만 가능합니다(네이티브 힌트에 대한 아래 섹션 참조).

pom.xml에서 다음과 같이 변경해야 합니다.

  • 추가하다 spring-native 의존
  • 추가하다 spring-aot-maven-plugin
  • 네이티브 빌드를 위한 스프링 리포지토리 추가
  • Buildpack을 사용하여 기본 이미지 또는 도커 이미지를 빌드하는 옵션
  • 의존성을 보장 runtime 스코프는 H2와 같이 스코프가 제거되었습니다. 아래를 참조하세요. 그렇지 않으면 네이티브 이미지 빌드가 실패하고 H2의 경우 불평합니다. package org.h3.server.web does not exist기본 이미지가 빌드 시 빌드되고 종속성이 다음과 같이 표시되므로 의미가 있습니다. runtime 범위는 빌드 시간 동안 표시되지 않습니다. 간단한 수정은 그냥 제거하는 것입니다 scope 해당 종속성에 대한 줄입니다.
<dependency>
<groupId>com.h3databasegroupId>
<artifactId>h3artifactId>
<scope>runtimescope>
dependency>

명심해야 할 한 가지 핵심 사항은 AOT 컴파일러가 빌드 시간 동안 훨씬 더 오래 걸린다는 것입니다(고객 서비스 기본 앱 빌드 시 8분 이상). 이는 개발 단계에서 바람직하지 않습니다. 이 문제를 해결하기 위해 여러 maven 프로필을 도입할 수 있습니다.

  • 그만큼 default 프로필을 사용하면 앱을 다음 없이 일반 Spring Boot 앱으로 실행할 수 있습니다. spring-native 의존. 이것은 개발 단계의 빌드에 이상적입니다. 개발자는 작업 중인 Spring Boot 앱이 Spring Native를 지원한다는 사실조차 알아차리지 못할 것입니다.
  • 그만큼 spring-native 프로필 추가 spring-native 의존성 및 AOT maven 플러그인. 이것은 Spring Native를 Spring Boot 앱에 굽습니다. 우리가 추가하고 있습니다 spring-native 이 프로필에만 종속되므로 default 프로필은 영향을 받지 않습니다 spring-native.
  • 그만큼 build-docker-image 프로필을 통해 앱을 Docker 이미지로 빌드합니다. paketobuildpacks/builder:tiny Docker 설치가 필요한 빌더.
  • 그만큼 build-native-image 프로필은 GraalVM 네이티브 이미지를 사용하여 앱을 네이티브 실행 파일로 빌드합니다.

spring.io에 따르면 이 글을 쓰는 시점에서 최신 Spring Native 버전 0.11.4는 Spring Boot 2.6.6에 대해 테스트되었습니다. 위에서 언급한 변경 사항, 특히 다른 프로필이 포함된 전체 pom.xml을 살펴보겠습니다.

3단계: Spring Boot 네이티브 앱 빌드

위에서 언급했듯이 Spring Boot 네이티브 앱을 빌드하는 방법에는 두 가지가 있습니다.

  • Spring Boot Buildpacks 지원을 사용하여 Docker가 이미 설치되어 있다고 가정하고 기본 실행 파일이 포함된 경량 컨테이너를 생성합니다.
mvn clean package spring-boot:build-image -Pspring-native,build-docker-image
  • 기본 빌드 도구를 사용하여 기본 실행 파일 생성.
mvn clean package spring-boot:build-image -Pspring-native,build-native-image

4단계: Spring Boot 기본 앱 실행

성공적인 Buildpack 빌드 후 build-docker-image, Docker 컨테이너를 시작하려면 다음을 실행하여 데모 네이티브 앱을 시작하십시오. 주의 --rm Docker가 컨테이너를 자동으로 정리하고 컨테이너가 종료될 때 파일 시스템을 제거하도록 지시하는 플래그가 추가되었습니다.

docker run --rm wenqi/customerservice:latest

네이티브 빌드 도구를 사용하여 네이티브 앱을 빌드하는 경우 build-native-image실행 파일이 아래에 생성됩니다. target 예배 규칙서. 우리의 경우 파일 이름은 com.github.wenqiglantz.service.customerservice.customerserviceapplication.exe. 실행 파일을 실행하여 앱을 실행하기만 하면 됩니다.

./target/com.github.wenqiglantz.service.customerservice.customerserviceapplication

0.696초! 놀라운!

이 두 데모 앱을 나란히 놓고 주요 데이터 포인트 중 일부를 비교하겠습니다. 부하 테스트는 VisualVM을 통해 모니터링하는 JMeter를 사용하여 수행되었으며 50명의 사용자는 고객을 생성하고 50명의 사용자는 고객 데이터를 검색합니다. 부하 테스트는 각 앱에 대해 5분 동안 진행되었습니다.

  • 고객 서비스: 구축 및 실행 amazon-corretto-17.0.1.12.1-windows-x64-jdk
  • 고객 서비스 네이티브: 구축 및 실행 graalvm-ce-java17-22.0.0.2.
  • 테스트는 Dell Latitude 7400, Intel Core i7–8665U CPU @ 1.90GHz, 2112Mhz, 4코어 및 8 논리 프로세서에서 수행됩니다. 16GB 램. OS Microsoft Windows 10 Enterprise, x64 기반.
  • 기본 Spring Boot 앱은 AOT 컴파일러로 인해 예상대로 빌드 시간이 훨씬 더 깁니다.
  • 기본 Spring Boot 앱은 GraalVM 및 AOT 컴파일러로 인해 설계된 대로 매우 빠른 시작 시간을 제공합니다. 이것이 Spring Native를 Spring Boot 앱에 통합하는 이유 중 하나입니다. 이러한 놀라운 성능 향상을 달성하기 위해 나는 긴 빌드 시간을 행복하게 살 수 있습니다. :-) 더 나은 아직, 우리는 사용할 수 있습니다 default 로컬 개발 빌드를 위한 maven 프로필을 생성하고 기본 이미지 빌드를 CI 파이프라인에 전달합니다.
  • 기본 Spring Boot 앱은 시작 시와 로드 시 메모리 사용량이 훨씬 적습니다. 기본 앱의 힙 크기와 사용 힙은 기본이 아닌 앱의 힙 크기보다 훨씬 낮습니다. 특히 로드 시 매우 인상적입니다! 네이티브 앱이 가야 할 길이라는 증거!

Spring Native Beta는 2021년 3월에 출시되었습니다. 최신 버전 0.11.4에서 다음과 같은 일반적인 Spring Boot 스타터 라이브러리를 지원합니다. 일부 라이브러리에는 구성 수정이 필요하므로 아직 완벽하게 원활한 환경은 아닙니다.

  • spring-boot-starter-data-jdbc
  • spring-boot-starter-data-jpa (구성 수정 포함)
  • spring-boot-starter-aop
  • spring-boot-starter-batch
  • spring-boot-starter-web (구성 수정 포함)
  • spring-boot-starter-actuator (구성 수정 포함)
  • spring-boot-starter-test (mockito는 아직 지원되지 않습니다)
  • 등.

Spring Native가 지원하는 라이브러리와 구성 수정이 필요한 라이브러리에 대한 자세한 목록은 Spring Boot Support에 대한 Spring 웹 사이트를 참조하십시오.

데모 네이티브 앱에서 작업하는 동안 JPA, OpenAPI 및 Liquibase를 포함한 종속성과 관련된 여러 문제에 부딪쳤습니다. 이 글을 쓰는 시점에서 Spring Native는 여전히 Liquibase를 지원하지 않으며 이 문제에 대한 공개 JIRA 티켓이 있습니다.

Spring Native에서 아직 지원하지 않거나 완전히 지원하지 않는 라이브러리가 꽤 있으므로 해결을 위해 Native Hint를 찾아야 했습니다.

Spring의 Native Hint 페이지에 명시된 대로 Spring Native에서 아직 지원하지 않는 기능이나 라이브러리를 사용하려면 아래에 정적 파일을 수동으로 추가할 수 있습니다. META-INF/native-image GraalVM 네이티브 이미지에 의해 자동으로 검색됩니다. 이것은 Spring Native 팀이 만든 흥미로운 용어인 "Native Hints"라고 합니다.

나는 실종되었다 PostgreSQLDialect 기본 앱 실행 중 오류가 발생했습니다. 다음 스니펫을 명시적으로 추가한 후 reflect-config.json 디렉토리 아래: META-INF\native-image\org\springframework\aot\spring-aot\reflect-config.json, 오류가 사라졌습니다. 예, 이 파일에서 클래스를 검색하기 위해 Spring Native에 수동으로 힌트를 제공하기 위해 추가해야 하는 새 디렉토리/파일입니다.

[
{
"name": "org.hibernate.dialect.PostgreSQLDialect",
"condition": {
"typeReachable": "org.postgresql.Driver"
},
"allDeclaredConstructors": true,
"allDeclaredMethods": true
}
]

또한 기본 앱 실행 중에 다음 Liquibase 오류가 발생했습니다.

Native reflection configuration for liquibase.configuration.LiquibaseConfiguration.() is missing

추가 후 LiquibaseConfiguration 수업하다 reflect-config.json, 누락된 다른 Liquibase 클래스와 관련된 일련의 추가 오류가 발생했습니다. 약간의 연구 끝에 나는 Liquibase에 대한 Spring Native의 지원 부족을 해결하기 위한 Josh Long의 솔루션을 발견했습니다. 다소 장황한 솔루션이지만 작동합니다. Spring Native가 보다 우아한 솔루션을 제공할 수 있을 때까지 우리는 현재 이 해결 방법을 사용해야 합니다. 내 GitHub 리포지토리에서 최종 버전을 확인하십시오. reflect-config.json.

패키지 명명 규칙에서 언급했듯이 Spring Native는 아직 "실험" 모듈에 있으며 이는 아직 완전히 프로덕션 준비가 되지 않았음을 의미합니다. 또한 기본 이미지에는 여전히 몇 가지 제한 사항이 있습니다.

  • 모든 Java 기능을 지원하지 않습니다.
  • 반사에는 특별한 구성이 필요합니다.
  • 게으른 클래스 로드를 사용할 수 없습니다.

또한 언급할 가치가 있는 것은 현재 Spring Native에 대한 지원이 다른 인기 있는 Spring 라이브러리만큼 풍부하지 않다는 것입니다. 커뮤니티는 아직 이를 적극적으로 수용할 준비가 되어 있지 않고 경계하고 있습니다.

Spring Native의 미래는 Spring Boot 3.x의 일급 기본 지원입니다! Spring Boot 3 AOT 및 기본 지원 목표:

  • Spring Boot의 원활한 통합
  • 네이티브 지원 증가
  • 네이티브 및 JVM을 위한 AOT 변환을 통한 런타임 효율성
  • 자바 17 베이스라인

Spring Boot 3 일반 출시 날짜는 현재 2022년 11월 말로 예정되어 있습니다. 강력한 Java 기본 에코시스템을 구축하기 위한 약속으로 Spring 팀은 Spring Boot 3이 향후 10년 동안의 프레임워크가 될 것이라고 약속합니다! 정말 신나는 시간!

Spring Boot 3 AOT 최적화 및 기본 지원은 수백만 개의 Spring Boot 애플리케이션에 도움이 될 것입니다. 이 중요한 릴리스를 간절히 기다리는 동안 Spring Native를 사용하여 Spring Boot 애플리케이션을 기본 실행 파일로 컴파일해 보겠습니다. Spring Native를 실험하는 과정에서 저는 Spring Native를 중심으로 더 많은 개발자 기반이 성장하여 서로에 대한 더 나은 공동 작업과 지원을 제공하는 것을 보고 싶었습니다. 그래서 우리 모두 Spring Native를 날개로 사용하여 Spring Boot에서 높이 날아가는 것을 경험하게 되었습니다. !

이 이야기에서 GraalVM, Native Image, AOT 컴파일러를 살펴봄으로써 Spring Native를 살펴보았습니다. 그런 다음 Spring Native를 기존 Spring Boot 앱에 통합하는 단계를 살펴보았습니다. 또한 Spring Native의 몇 가지 제한 사항을 살펴보았습니다. Spring Native와 Spring Boot 3의 미래는 매우 흥미진진합니다! 이 이야기를 통해 Spring Native가 무엇인지, 장단점, 그리고 매우 유망한 미래에 대해 더 잘 이해할 수 있기를 바랍니다.

데모 앱에 대한 내 GitHub 리포지토리를 확인하세요.

즐거운 코딩!

반응형

댓글0