영감을 (inspire) 주고픈 개발 블로그

[성능테스트 시리즈 - 2] Spring boot 3.2 features: Virtual Thread 성능 측정해보기 본문

개발/시스템 안정성 flow

[성능테스트 시리즈 - 2] Spring boot 3.2 features: Virtual Thread 성능 측정해보기

inspire12 2023. 12. 25. 16:03

이전글: https://inspire12.tistory.com/326

 

간편하게 백엔드 서버 성능 테스트 시스템 세팅하기: docker-compose를 성능 테스트를 쉽게 모니터링

성능테스트란? 서버 성능 테스트를 진행하면 서버가 어느 정도 부하에 대해 버틸 수 있는지 눈으로 확인해 볼 수 있다. 라이브 서버에 올리기 전 혹은 사용자가 몰릴 수 있는 이벤트를 진행할 때

inspire12.tistory.com

 

테스트 시스템 세팅해 봤으니 이번엔 예제를 만들어보겠습니다. 

 

마침 Spring boot 3.2 정식 릴리즈로 인해 Spring6에 대한 관심도가 늘었고 특히 새로운 feature인 virtual thread에 대해 공부할 겸  성능을 비교한 article이 있어 virtual thread 도 정리하고 해당 따라 테스트를 진행해 보겠습니다. 

https://www.baeldung.com/spring-6-virtual-threads

 

Virtual thread 과 Platform thread의 다른 점

1. Virtual Thread는 OS Thread에 의존하지 않습니다. JVM에서 제공하는 추상층을 통해 하드웨어에 덜 영향을 받습니다 

2. Platform thread 보다 더 싸게 쓸 수 있습니다 (하드웨어 자원을 덜 소모)

 

실습 코드 받기, 참고글

 

코드 세팅

mkdir -p ~/Documents/workspace/sparse-project
cd ~/Documents/workspace/sparse-project

rm -rf .git
git init 
git remote add origin https://github.com/inspire12/inspire12-blog-code.git

git config core.sparsecheckout true
echo 'inspire12-loadtest/*' >> .git/info/sparse-checkout
git pull origin main

cd inspire12-loadtest
idea .

 

 

문서에 있는 대로 코드를 구현했습니다. 다만 기존 프로젝트가 Gradle이고 위의 문서가 초창기 19 버전으로 써진 거라 자바 21 버전의 Spring boot 3.2에서 진행을 했습니다. 

 

java 버전이 달라지면 intellij에서 프로젝트를 못 잡는 경우가 있는데요. 이 경우는 아래처럼 진행하시면 잡을 수 있습니다. 

 

설정 > 빌드, 실행, 배포 > 빌드도구 > Gradle > Gradle JVM 버전을 21로 변경 (없다면 JDK 다운으로 해결)

 

 

 

 

inspire12-loadtest의 application.yml 파일에서 virtual 스레드를 설정된 부분의 주석을 풀어 활성화시킵니다

#spring:
#  thread-executor: virtual
#  threads:
#    virtual:
#      enabled: true

 

문서에 있는 프로젝트 실행 후 curl을 통해 스레드 확인 결과 화면

curl -s https://localhost:8080/thread/name 

 

 

 

성능 비교 

그럼 성능 비교를 진행해 보겠습니다. 우선 성능 비교 세팅을 진행하겠습니다. 위처럼 sparsecheckout을 진행하여 performance 결과 값 세팅을 진행하겠습니다  

 

cd ~/Documents/workspace/sparse-project

rm -rf .git
git init 
git remote add origin https://github.com/inspire12/inspire12-blog-code.git

git config core.sparsecheckout true
echo 'jmeter-influxdb-grafana-docker/*' >> .git/info/sparse-checkout
git pull origin main

jmeter

(jmeter gui가 깔려있지 않으면 위의 접은 글을 참고해주세요)

 

jmeter를 실행한 후 open에서 jmeter-influxdb-grafana-docker/jmeter-scripts/example.jmx를 열고 아래와 같이 설정을 바꿔주시면 됩니다 

 

Thread Group은 Spring 문서랑 동일합니다 

 

Http Request는 문서에는 없지만 loadtest api를 단순 호출하는 것이라 쉽게 작서했습니다

 

 

실행 전 프로그램들을 닫고 top 명령어로 우선 컴퓨터의 상태를 캡처했습니다 

 

virtual thread로 부하 테스트를 실행 후 컴퓨터의 상태를 캡쳐했습니다 

 

platform thread로 부하 테스트를 실행 후 컴퓨터의 상태를 캡쳐했습니다 

둘을 비교하면 확실히 idea에서 CPU 상태를 98.4 vs 77.2로 나옵니다. 이건 테스트를 실행한 컴퓨터 상황에 따라 다르게 나올 수 있습니다. 그래도 virtual thread에서 idea의 CPU를 더 쓰는 건 예상외였습니다.

 

지표값 확인 

http://localhost:3000/dashboards 여기의 General > Jmeter Dashboard로 접속 후 application Example, Last 5 minute으로 본 지표입니다 

 

 

결과는 spring article에서 이야기한 것과 거의 동일하게 나왔습니다. 아래가 응답시간으로 같은 코드인데도 왼쪽인 virtual thread가 더 안정적이고 높은 사용량을 보여주고 있습니다. 

오른쪽인 platform thread는 실행 후 1초에서 부하가 지속될수록 응답시간이 늦어지다가 5초에서 머물게 됩니다

 

문서에선 

This is happening because platform threads are a limited resource, and when all the scheduled and pooled threads are busy, there is nothing left for the Spring App to do than put the request on hold until one thread is free.

 

platform thread의 경우 자원의 한정으로 예약 및 풀링 된 모든 스레드가 사용 중일 때 하나의 스레드가 여유가 생길 때까지 요청을 보류하는 것 외에는 Spring 앱이 할 수 있는 일이 없기 때문에 이러한 일이 발생한다고 합니다. 

 

virtual thread를 썼을 때 즉각적이고 더 싸게 리소스를 사용한다는 걸 알 수 있었습니다.

 

다만 이 실험에서 주의할 점은

we are comparing the usage of the spring default fixed standard thread pool (which is by default at 200) and the spring default unbounded pool of Virtual Threads.

스프링 기본 고정 표준 스레드 풀(기본적으로 200)과 가상 스레드의 스프링 기본 무제한 풀의 사용량을 비교하고 있다는 것과

This kind of performance gain is only possible because the scenario is simplistic and doesn’t consider the whole spectrum of what a Spring Boot application can do. 

(Spring이 실행할 수 있는 전체 범위를 고려하지 않고) 다른 실행 없이 최대한 단순하게 비교한 것이라는 것이기 때문에 모든 케이스에 적용되지 않을 수 있습니다.

 

추신)

앞에 제가 썼던 두 가지 방법을 통해 blog-code를 통해 빠르게 성능테스트 시스템을 만들어보고 다른 분이 만든 성능 비교 문서를 따라 해보고 검증해 볼 수 있었는데요. 

 

이 글을 보시고 따라 하시다 안되거나 좀 더 친절한 설명이 필요하다면 건의해 주세요 반영하겠습니다.

감사합니다