본문 바로가기

공부/백엔드

[JMeter] 성능 측정 도구로 성능 테스트 및 개선 수치 파악

반응형

 

 

프로그램을 개발할 때, 특히 백엔드 서버를 개발할 때 성능 개선은 중요합니다!

저는 평소에 "이렇게 하면 더 빠르겠지?"라고 생각하며 개발하곤 하지만 성능을 제대로 측정하고 비교해본 적이 없었어요.

직접 실행해서 확인하는 방식으로는 정확히 개선이 되었는지 확인하기 어렵고, 부하를 줄 만큼의 요청을 하기도 어렵습니다.

그렇기 때문에 성능 측정을 하는 도구에 대해 알아보고 사용해보려고 합니다.


성능 테스트의 목적

성능 테스트는 여러 상황에서 성능을 보장하기 위한 수단입니다.

특히 높은 트래픽 또는 장시간의 트래픽에서 안정성과 속도 등이 유지될 수 있는지를 테스트해야합니다.

 

  • 부하 테스트 : 최대 처리량의 부하을 가하는 테스트
  • 스트레스 테스트 : 정상보다 더 많은 (최대 처리량의 약 2배) 부하를 주는 테스트
  • 스파이크 테스트 : 순간적으로 사용자 수를 증가시키는 테스트

이러한 테스트를 통해 병목 구간을 해결하고, 실제 서비스에서 발생하는 사용자 추이에 따라 적당한 성능의 자원을 배분할 수도 있습니다.

또 성능에 영향을 줄 수 있는 부분은 데이터베이스, 네트워크, 소프트웨어, 하드웨어 등 다양하게 있다는 것을 인지하고 찾아가야 합니다.

 

또한, 임계점에 다다를수록 시간에 수렴하는 형태가 안정적이고 일관된 성능을 제공하여 가장 이상적입니다.

비례하게 증가하는 경우는 사용자가 많아질수록 점점 느려지고, 사용자에 수렴하는 형태는 서비스 장애가 발생할 확률이 커집니다.

 


기본적인 실행 시간 측정

일단 툴이 아니어도 간단하게 성능 측정을 하는 방법은 있습니다.

- System.currentTimeMillis() : 현재 시간을 나타내는 값을 ms(밀리세컨드)로 리턴 *1000ms = 1초

- System.nanoTime() : 현재 시간을 ns(나노세컨드)로 리턴 *1,000,000,000ns = 1초

long startTime = System.currentTimeMillis();
// 로직 수행
long .endTime = System.currentTimeMillis();
System.out.println("수행 시간(초) : " + (endTime - startTime)/1000);

 

해당 메서드를 통해 위와 같이 개별 로직에 대해 간단히 시간을 측정해볼 수 있습니다.


Profiler를 이용한 애플리케이션 분석

: 애플리케이션 내부 성능을 분석할 수 있는 도구로 CPU, 메모리 사용량, 메소드 실행 시간부터 메소드 호출 순서와 빈도, 객체 메모리 사용량 등을 조회할 수 있습니다.

 

IntelliJ나 Eclipse 등 IDE에서 내부적으로 사용할 수 있도록 제공하고 있습니다.

아래 사진은 IntelliJ에서 Profile을 수행하여 메서드 별 실행 시간을 조회한 것입니다.


JMeter로 부하 테스트

: 프로파일러처럼 리소스 및 시간 분석과 더불어 가상 사용자를 이용한 부하 테스트를 할 수 있는 도구입니다.

 

HTTP 요청 테스트

HTTP 요청 테스트는 HTTP 프로토콜의 웹서버로 원하는 만큼의 요청을 보낼 수 있는 테스트입니다.
JMeter는 여러 종류의 테스트를 할 수 있는데, 이번 포스팅에서는 HTTP 테스트를 수행해보도록 하겠습니다.

 

@GetMapping("wait")
public String wait1Second(@RequestParam long sec) throws InterruptedException {
    Thread.sleep(sec * 1000);
    return "done";
}

 

 

쿼리 파라미터로 준 sec값 만큼 대기 후, "done"을 리턴하는 간단한 GET API를 테스트 해보도록 하겠습니다.

 

 

 

먼저 스레드 그룹을 설정합니다.

몇 초 간격으로 몇 개의 사용자(스레드)가 요청을 보내고, 이를 몇 번 반복할지에 대한 설정입니다.

위 사진의 경우 1초마다 10명의 사용자가 요청을 보내고 이를 10번 반복합니다.

 

 

먼저 HTTP Request를 추가하여 IP(host)와 Port, Http method, url path를 입력합니다.

그 외에 파라미터나 Body 같은 데이터도 포함하여 보낼 수 있습니다.

위 사진과 같이 입력하면 http://127.0.0.1:8080/wait?sec=1 이라는 url로 요청을 보내게 됩니다.

앞에서 코드에서 봤듯이 해당 요청은 1초만큼 쉬고 리턴하게 됩니다. 즉, Response time이 대략 1초라고 생각하면 됩니다.

 

이렇게 요청과 스레드 그룹을 설정했다면 원하는 결과를 조회할 수 있습니다.

 

 

Response Assertions은 HTTP의 예상 응답을 설정하여 실제 값과 일치하는지 비교하는 동작을 수행합니다.

Response Code(상태 코드), Text Response(Body), Header 등에서의 값을 테스트 할 수 있습니다.

저는 사진과 같이 상태 코드가 200이 되어야 한다는 조건을 설정해두었습니다.

 

 

Response Assertions에서 예상한 값이 성공적으로 나오면 View Results Tree에서 다음과 같이 응답값과 함께 초록색 체크 표시를 확인할 수 있습니다.

사진은 없지만, 실패한 경우에는 빨간색 X 표시를 확인할 수 있습니다.

 

다음으로 JMeter Plugins Manager를 설치하면 확인할 수 있는 기능을 활용해보겠습니다.

 

 

먼저 Transaction Per Seconds (TPS) 그래프를 확인할 수 있습니다.

아까 10초동안 1초 간격으로 10명의 사용자가 요청을 보내라고 스레드 그룹을 설정해두었습니다.

그렇기 때문에 그래프에서도 10초까지 평균적으로 10개의 트랜잭션이 발생하고 있는 것을 볼 수 있습니다.

 

 

Response Time을 테스트하는 그래프입니다.

앞에서 한 요청 당 1초가 걸린다고 했는데, 위 그래프에서도 응답 시간에 평균적으로 1,000ms에 분포돼있는 것을 확인할 수 있습니다.

 

 

이렇게 간단하게 코드 실행 시간 분석, HTTP 부하 테스트를 수행해보았습니다.

앞으로도 다양하게 성능을 측정하며 더 효율적인 코드를 짤 수 있도록 해야겠습니다.

 

포스팅 봐주셔서 감사합니다.

반응형