spring aot , graal vm 적용 실패기

유형찬·2023년 6월 25일
0
post-custom-banner

2가지 방법 Gradle 사용

두 가지 방법 모두 graalVm 을 사용한다.

주의점은 런타임 시점에서 yml 환경 값을 주입 받지 못하기 때문에 aws 파라미터 스토어를 사용 할 수 없다.

sdk list java 

sdk install java 21.1.0.r11-grl -> graalVm 설치 없을 수 잇음 list 보고 체크

sdk use java 21.1.0.r11-grl

java -version

아래에 이것만 추가하면 nativeCompile 사용 가능하다.


plugins{
    id 'org.graalvm.buildtools.native' version '0.9.23'
}

1. bootBuildImage

1.1. build.gradle bootBuildImage

도커 이미지로 빌드 하는 경우 bootBuildImage 를 사용한다.

bootBuildImage {
    imageName = "gudcks305/spring-boot-docker"
    builder = "paketobuildpacks/builder:base"
}

m1 mac 에서 빌드하는데도 시간이 매우 오래 걸리며 cpu 사용량이 하늘을 찌른다.

피크 cpu 사용량이 99%가 넘어가며 메모리 사용량이 8기가 정도 된다. 허허...

심지어 msa 프로젝트라 각 서버의 의존성이 그리 크지 않은 상태임에도 불구하고 빌드 시간이 10분이 넘어간다.

사실 쓰고있는 시점에서도 빌드가 되지 않았다.

보아라 이 엄청난 사용량을...

cpu 사용량이 미친 수준이다. 이걸 사용하라고 만든 수준인가? 싶을 정도...

m1으로 바꾸면서 cpu 사용량이 부족한 적은 없었는데 4코어가 할당 된걸 보니 미친 수준이다.

아무리 그래도 그렇지... 사실상 scale-out 을 하는 서버 입장에서는 진짜 사용 불가능한 수준 이다.

아니 warm-up time 을 줄이기 위해서 쓰는데 배보다 배꼽이 더 크다. 이미지 빌드 리소스 사용량이 너무 많다.

뭐랄까 ci/cd로 자주 업데이트 사항을 반영하는 개발론적 관점에서는 적합하지 않은 것 같다.

로그를 보면 reflection 관련 클래스 하나에 수 분이 걸리는 것 같다.

2023-06-25 11:35:11 Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#kotlinSerializationCborPresent set to false at build time
2023-06-25 11:35:11 Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#kotlinSerializationJsonPresent set to false at build time
2023-06-25 11:35:11 Field org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#kotlinSerializationProtobufPresent set to false at build time
2023-06-25 11:35:45 Field org.springframework.boot.logging.logback.LogbackLoggingSystemProperties#JBOSS_LOGGING_PRESENT set to true at build time
2023-06-25 11:36:45 Field org.springframework.boot.autoconfigure.web.format.WebConversionService#JSR_354_PRESENT set to false at build time
2023-06-25 11:38:11 Field org.springframework.boot.jdbc.DataSourceUnwrapper#DELEGATING_DATA_SOURCE_PRESENT set to true at build time
2023-06-25 11:38:48 Field org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver#AGENT_CLASS_PRESENT set to false at build time
2023-06-25 11:39:08 Field org.springframework.web.servlet.mvc.method.annotation.ReactiveTypeHandler#isContextPropagationPresent set to false at build time

음 어... 그만 알아보자

1.2 gradle nativeCompile

nativeCompile 을 사용하는 방법이다.

실제로 실행 응용프로그램을 만들어서 실행하는 법 이다.

주의점은 런타임 시점에서 yml 환경 값을 주입 받지 못하기 때문에 aws 파라미터 스토어를 사용 할 수 없다.

추가적인 + 설정이 필요 할 것 같은데 어떻게 하는지 모르겠다!!!

일단 파라미터 스토어 존재시 env 값을 런타임에 주입하지 못해서 그런지는 모르겠지만 작동을 하지 않는다 ㅠ

하지만 빌드 시간은 확실히 빠르고 리소스 사용량도 확실히 적은 편

load 시간 약 7분 이후 처리 시간 73초로 약 6~10분 정도의 시간이 걸리고 있다.

이것을 보면 크게 나쁘진 않을 것 같다. 일단 파라미터 스토어의 문제로 실행할때 실패하는 문제가 있긴 하다.

[native-image-plugin] Native Image written to: ${yourPath}

위 처럼 만들어진 path 가 나오게 되고 이것을 실행하면 된다.

./${yourPath}

실행 시간이 확실히 빠르긴 하다..? 명령어를 치자마자 에러가 나온다 허헣

문제점

현재 aws-parameter-store 사용 중이며 spring-config 기술로 이전 할 것 이지만, 둘 모두 런타임 시점에서 환경 값을 주입 받는데 이것이 aot의 경우 컴파일 시점에서 환경 변수를 넣어줘야 하는데 둘 모두 이것을 지원하지 않기 때문에 사용 할 수 없다.

shell script 로 환경 변수를 넣어줘 사용 할 수는 있겠지만 번거로울 부분이 상당히 많다.

#!/bin/bash

# Config 서버 URL. 실제 사용할 URL로 변경 필요.
CONFIG_SERVER_URL="http://your-config-server.com/app/profile"

# Config 서버에서 JSON 형태의 설정 값을 가져옵니다.
CONFIG_JSON=$(curl -s $CONFIG_SERVER_URL)

# JSON 을 파싱하여 "key=value" 형태로 출력합니다.
CONFIG_KEYS_VALUES=$(echo $CONFIG_JSON | jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]')

# 출력된 각 "key=value" 를 환경 변수로 저장합니다.
IFS=$'\n' # 개행 문자를 구분자로 설정
for kv in $CONFIG_KEYS_VALUES; do
    key=${kv%%=*}    # "=" 앞의 문자열 (key) 을 추출
    value=${kv#*=}   # "=" 뒤의 문자열 (value) 을 추출
    export $key=$value  # 환경 변수로 저장
done

뭐 이런식으로 임시 환경 변수를 넣어줘 처리를 할 수 는 있겠으나 이것도 번거로울 것 같다.

외부에서 환경 값을 받고 있기 때문에 사실 적용 할 수 없는... aot 기술...

장단점 정리

단점

일단 빌드 시간이 너무 오래 걸린다. m1에서도 이런 시간이 걸리면 도대체 서버의 낮은 리소스로는 얼마나 걸릴까??

빌드 시간이 너무 오래 걸리고, 빌드 시간이 오래 걸리는 만큼 리소스 사용량도 많다. 배보다 배꼽이 더 큰 것 같다.

또한 spring-config , aws-parameter-store 를 사용 할 수 없다. 외부에서 환경 값을 컨트롤 할 수 있는 기술을 사용 할 수 없다.

빠르다.

실행 시간이 확실히 빠르다. 추후 테스트를 해봐야겠지만, 빌드 시간이 오래 걸리는 만큼 실행 시간이 확실히 빠르다.
현재는 develop이 우선이기 때문에 이런 쟁점이 있다 파악만 해두고, 실제 운영에 적용은 안정화가 되고 적용해 보면 좋을 것 같다. 그리고 일단 기술 성숙도가 낮기 때문에 실제 사용은 조금 어려운 부분이 있을 수 밖에 없을 것 같다.

결론

현재는 시기 상조, 들어내야할 기술이 많음, 기술 성숙도가 낮음 등의 이유로 실제 적용은 어려울 것 같다.

profile
rocoli에요
post-custom-banner

0개의 댓글