본문 바로가기
자습

Spring Native

by litaro 2022. 5. 14.

Go + goFiber 로 서버를 개발하다가 올해 Java + Spring Boot 로 서버를 개발하니 서버 실행 시간과 속도, 메모리 사용량에 당황하게 된다. 

물론 Spring 이 오랜시간 축적하여 제공하는 다양한 기능과 안정성은 이러한 서버 성능의 단점을 넘어서기때문에 아직도 Spring을 많이 사용하는것이다.

Spring에서도 JVM위에서돌아가는 Spring 서버의 성능의 한계를 알았는지 2021.3.11 에 Spring Native Beta를 Release 하게된다.

https://spring.io/blog/2021/03/11/announcing-spring-native-beta

 

Announcing Spring Native Beta!

<div class="paragraph"> <p>Today, after one year and half of work, I am pleased to announce that we’re launching the beta release of <a href="https://github.com/spring-projects-experimental/spring-native">Spring Native</a> and its availability on <a href

spring.io

 

1년이 조금 넘은 따끈따끈한 Spring Native를 한번 적용해서 얼마나 성능이 좋아지는지 확인해배보자 

테스트용 서버를 만들기는 귀챦으니 내가 구현한 서버를 그대로 한번 Native Image로 만들어보자

테스트 서버는 Redis와 MongoDB를 사용하는 간단한 서버

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
    implementation 'org.projectlombok:lombok:1.18.22'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
...
}

Spring Native Image 만들기

Spring Native Image는 GraalVM native-image 를 이용해서 만든다.  

Sprint Native Image의 장점

Using native image provides key advantages, such as instant startup, instant peak performance, and reduced memory consumption.

Spring Native Image 의 단점

Building a native image is a heavy process that is slower than a regular application. A native image has fewer runtime optimizations after warmup. 

https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#getting-started

 

Spring Native documentation

The GraalVM native image tracing agent allows to intercept reflection, resources or proxy usage on the JVM in order to generate the related native configuration. Spring Native should generate most of this native configuration automatically, but the tracing

docs.spring.io

가이드를 보면 두가지 방법이 가능하다.

  • Getting started with Buildpacks
    • docker를 이용해 native application을 생성해줄 linxu container를 띄워서 GraalVM native image compiler를 사용해서 서버의 docker image 생성
    • docker run으로 생성된 서버 image 실행하면 끝
    • 하지만, 쉽지 않았다. 선호하는 방법이었으나 가이드에 맞게 docker 메모리 할당도 변경하고 build.grade, setting.gradle을 변경했지만 어느 시점에서 멈춰서는 40분이 되도록 아무 반응이 없었다. 에러라도 나면 수정하겠는데 ... 이 방법은 PASS 
  • Getting started with Native Build Tools
    • native build tool을 직접 내 PC OS에 맞게 설치

Native Build Tool 설치

https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#_linux_and_macos

 

Spring Native documentation

The GraalVM native image tracing agent allows to intercept reflection, resources or proxy usage on the JVM in order to generate the related native configuration. Spring Native should generate most of this native configuration automatically, but the tracing

docs.spring.io

SDKMAN 설치

# 설치
curl -s https://get.sdkman.io | bash
# 설정
source "$HOME/.sdkman/bin/sdkman-init.sh"
# 확인
sdk version
SDKMAN 5.15.0

GraalVM native-image distribution 설치

⚠️ 가이드가 맞지 않다. 

sdk install java 22.0.0.r11-nik

Stop! java 22.0.0.r11-nik is not available. Possible causes:
 * 22.0.0.r11-nik is an invalid version
 * java binaries are incompatible with your platform
 * java has not been released yet

Tip: see all available versions for your platform:

  $ sdk list java
  
# 다시 설치
sdk install java 22.1.0.r17-grl

# 해당 JDK 사용
sdk use java 22.1.0.r17-grl

# native image extensions 을 해당 JSK에 가져오기
gu install native-image

# Java Version 확인해보기
java --version
openjdk 17.0.3 2022-04-19
OpenJDK Runtime Environment GraalVM CE 22.1.0 (build 17.0.3+7-jvmci-22.1-b06)
OpenJDK 64-Bit Server VM GraalVM CE 22.1.0 (build 17.0.3+7-jvmci-22.1-b06, mixed mode, sharing)

 


Spring Boot Project Setup

기존 Project에서 설정을 추가할 부분은 build.gradle, settings.gradle 파일이다.

build.gradle

plugins {
    id 'org.springframework.boot' version '2.6.5'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id 'jacoco'
    id 'org.springframework.experimental.aot' version '0.11.5'✅
}

repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/release' }✅
}

settings.gradle

pluginManagement {✅
    repositories {
        mavenCentral()
        maven { url 'https://repo.spring.io/release' }
        gradlePluginPortal()
    }
}
rootProject.name = ...

Build the native application

나의 경우 6분정도 걸렸다. ^^;;

./gradlew nativeCompile

 

build/native/nativeCompile/ 경로에 생성


Run the native application

build/native/nativeCompile/testserver

비교 테스트

서버 실행시간

Spring
Spring Native

서버 응답 시간

  • 테스트 : 간단하게 평균 응답 시간을 보기위해 테스트 진행
    • Tool: Locust 
    •  조건: Number of users (10) , Spawn rate (1), Host (localhost:8080)
  • 평균 시간 (ms) : Go (6) < Spring Native (9) < Spring (13)

 

Spring
Spring Native
Go

Summary

  • Spring Native Image는 GraalVM Compiler를 이용해서 Java byte code를 platform-specific, self-contained, native executable 로 Compile하여 좀더 빠르고 가볍다.
  • Spring Native Image를 생성하는 방법은 Cloud Native Buildpack + Docker 활용한 방법과 GraalVM Native Build Tool을 사용하는 두가지 방법이 있다.
  • SDKMAN을 사용하면 GraalVM Native Build Tool을 간단하게 설치해서 Mac OS용 Spring Native Image를 만들수 있다.
  • Spring, Spring Native, Go 세가지 버전에 대해 Locust로 간단한 HTTP 테스트를 진행했을때 응답시간을 보면 Spring Native는 Go와 Spring 의 중간에 위치하였다.

'자습' 카테고리의 다른 글

Go Thread-Safety : sync.Mutex, sync.Map  (0) 2023.08.26
go gRPC Server & gRPC Gateway  (0) 2021.09.20
Kong Gateway + Konga  (0) 2021.08.29
Jaeger with Go  (1) 2021.07.20
Zipkin Go  (0) 2021.07.17