성능 최적화를 위한 부하테스트 준비

김소희·2025년 12월 11일

2년전 국비 교육에서 스프링 부트를 막 배웠을 때 만들었던 프로젝트를
포트폴리오로 쓸 수 있게 리팩토링해서 포트폴리오로 만들겠다는 목표를 세웠다.

당시에도 시연할 수 있게 동작하게끔 완성하긴 했지만,
시간에 쫓기며 구글링하며 기능 구현에 급급했기 때문에
지금의 내눈에는 아쉬운점이 많이 보인다.

(당시의 코드가 부끄럽기도 하지만
그만큼 성장했구나 싶은 생각이 들어서 기쁘기도 하다.)

어떻게 개선하면 좋을지, 고도화에 대한 고민을 하게 되었고,
리팩토링 전/후 성능 차이를 수치로 비교할 수 있는 기준을 만들고 싶었다.

성능 차이를 비교하려면 무의미한 데이터라도 좋으니
더미데이터를 10만건 정도는 넣은 상태에서 하는 것이 좋다.

부하 테스트

부하테스트 툴인 nGrinder와
자원 모니터링을 위한 스카우터를 사용하여 성능 변화를 측정해보려고 한다.

nGrinder

nGrinder는 네이버(NAVER)에서 개발하여 오픈소스로 공개한 성능 테스트(Load Test) 자동화 플랫폼으로 Controller와 Agent로 구성되어 있다.
nGrinder는 기본적으로 'Maven(메이븐)' 기반으로 동작하고 아래 깃허브에서 jar파일을 다운로드 할 수 있다.

이후 새폴더에 jar파일을 담고 압축을 푼 다음에 cmd에서 컨트롤러 명령어를 입력한다.

java -jar ngrinder-controller-3.5.9-p1.war --port=8300 // 일반적인 실행하기

http://localhost:8300/login 경로에 접속해서 admin/admin으로 로그인이 가능하다. 로그인을 하면 Agent를 다운로드 받을 수 있다.

Agent

Agent는 Controller의 명령을 받아 부하를 실제로 발생시키는 역할을 한다.

다운받은 Agent도 nGrinder와 같은 폴더에 넣고, 명령어로 압축을 푼 다음
./run_agent.sh(mac) ./run_agent.bat(window) 명령어로 실행하자.

tar -xf ngrinder-agent-3.5.9-p1-localhost.tar // 압축풀기

이제 초록색 stats로 정상실행된 것을 알 수 있다.

테스트 스크립트 작성

http://localhost:8300/script 에서 create 버튼으로 스크립트를 생성한다.
스크립트 네임을 만들고 테스트 하고자 하는 url을 입력하자.

  • localhost를 사용할 수 없으니 127.0.0.1로 할 것.
  • 클라이언트 url로는 테스트 불가
  • https로 테스트 불가

이후 스크립트를 생성했지만 Validate에서 오류가 뜬다.

Java 17/21 + nGrinder의 DNS 내부 API 호환성 문제
-> JDK8 설치 실패 -> JDK11 설치 성공 !!
nGrinder 에러 - Unsupported class file major version 61 해결방법

Agent 폴더 (ngrinder-agent) 안에 있는 run_agent_internal.bat 파일을 변경한다.

@ECHO OFF
setLocal EnableDelayedExpansion

REM ******** [1] Worker Process 실행 시 사용할 JVM 옵션만 환경 변수로 주입 ********
REM 이 변수가 Worker Process가 DNS 오류 없이 시작되도록 돕습니다.
set NGRINDER_AGENT_INTERNAL_JVM_OPTIONS=--add-exports java.base/sun.net.spi.nameservice=ALL-UNNAMED
set JAVA_OPTS=%NGRINDER_AGENT_INTERNAL_JVM_OPTIONS%
REM ******************************************************************************

for /R ./lib %%a in (*.jar) do (
    set CLASSPATH=!CLASSPATH!;%%a
)
set CLASSPATH=!CLASSPATH!

REM [2] Agent 실행 명령: JDK 11 환경변수를 사용하며, DNS 옵션을 이중 주입
java %JAVA_OPTS% --add-exports java.base/sun.net.spi.nameservice=ALL-UNNAMED -server -cp "lib/ngrinder-core-3.5.9-p1.jar;lib/ngrinder-runime-3.5.9-p1.jar;%CLASSPATH%" org.ngrinder.NGrinderAgentStarter --mode agent --command run %*

검증을 성공했으면 save를 하자.

save후 Performance Test탭으로 가서 create Test로 생성하기.

save and start버튼을 눌러 테스트를 실행하면 콘솔창에 끊임없이 로그들이 지나간다.

3500건의 테스트가 정상적으로 실행되었고, 평균 TPS 143과 Peak TPS 214를 확인할 수 있었다.
TPS가 높고 Mean Test Time이 낮을수록 성능적으로 긍정적이다.


nGrinder 관련 용어 정리

TPS

  • Tramsactions Per Second의 약자로 초당 처리가능한 트랜잭션의 수
  • TPS가 100이라면 초당 100개의 작업을 처리할 수 있다고 볼 수 있다.
  • TPS가 높을 수록 짧은 시간에 많은 작업을 처리할 수 있다고 볼 수 있다.

vUser

  • Virtual User를 의미하며 가상 사용자를 뜻한다.
  • vUser 10은 10명의 가상 사용자가 동시에 시스템(애플리케이션)에서 동작하고 있음을 의미한다.

결과

  • Total Vusers : 가상 유저수
  • TPS: 평균 TPS
  • Peak TPS : 최고 TPS
  • Mean Test Time : 하나의 작업을 테스트 하는데 들었던 평균 시간
  • Executed Tests : 테스트 실행 횟수
  • Successful Tests : 테스트 성공 횟수
  • Errors : 에러 회수
  • Runtime : 테스트 실행 시간

스카우터 설치하기

모니터링 툴에는 Pinpoint, Elastic APM 등등 다양한 목적에 맞는 툴을 사용하면 된다.
이번에는 실시간 모니터링에 강한 Scouter를 써볼 것이다.

스카우터 서버 다운로드에서
스카우터 컨트롤러와 Agent를 포함하는 scouter-all-[version].tar.gz와
클라이언트를 담당하는 scouter.client.product-[os].tar.gz 다운로드 받기

폴더 새로 만들어서 파일 이동시키고 cmd 경로 찾아가서 tar -xf scouter-all-2.21.1.tar.gz 압축풀기

Java 17은 보안이 강화되어 있어서
Scouter를 Spring Boot 애플리케이션에 붙이기 위해 JVM 실행 옵션을 추가하여 실행한다.
server 폴더의 startup.bat파일을 메모장으로 열어서 아래 내용으로 변경

java -Xmx1024m --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/sun.misc=ALL-UNNAMED --add-opens=java.base/jdk.internal.reflect=ALL-UNNAMED -classpath ./scouter-server-boot.jar scouter.boot.Boot ./lib

server 폴더 경로에서 startup.sh(mac) 이나startup.bat(window) 명령어로 실행

클라이언트는 scouter.client 폴더에서 scouter.exe 더블클릭으로 실행가능하며
admin/admin으로 로그인 할 수 있다.

이제 테스트 할 서버를 실행하기 전에 Scouter 에이전트 프로그램을 BackendApplication에 주입하는 역할과 에이전트 설정 파일(서버 IP 등)이 어디 있는지 알려주는 설정을 곁들여서 실행해야하므로 Edit Configurations 옵션을 설정한다.

주의 사항 : 절대 경로를 사용할 것, 그래도 경로가 길면 Edit Configurations 옵션에서 Modify options -> Shorten command line 체크 활성화 -> Shorten command line에서 JAR manifest 선택하기

VM Options에 추가

-javaagent:C:\Users\lisso\Desktop\scouter\scouter\agent.java\scouter.agent.jar
-Dscouter.config=C:\Users\lisso\Desktop\scouter\scouter\server\conf\scouter.conf
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/sun.misc=ALL-UNNAMED
--add-opens=java.base/jdk.internal.reflect=ALL-UNNAMED

cmd에서 jar 직접 실행할 때 예시 (가급적이면 인텔리제이로 하세요.)

java -javaagent:C:\scouter\agent.java\scouter.agent.jar -Dscouter=C:\scouter\server\conf\scouter.conf -jar app.jar

어플리케이션을 실행하고 지표화면을 보면 톰캣부분도 활성화되어 있음을 확인할 수 있다.

agent.host 설정하기

OS에 CPU, Memory정보를 확인하기 위해 설정해야한다.
/scouter/agent.host/conf/scouter.conf열기
2~4째 줄 주석 풀기

./host.sh(mac), host.bat(window)로 실행하기

이제 운영체제 관련된 자원도 스카우터로 확인할 수 있게 된다.


참고자료

인프런 강의 - 백엔드 개발자 성능 개선 초석 다지기

2023년에 개발된 프로젝트 기술 스택
Java 11, Spring boot 2.7.13

2025년에 개발된 프로젝트 기술 스택
Java17, Spring boot 3.5.7

profile
개발자 소희의 노트

0개의 댓글