웹 어플리케이션 성능 테스트를 툴은 자바 오픈 소스 Apache Bench, Apache JMeter, 네이버에서 Grinder를 이용해서 만든 nGrinder, Gatling 등등이 있습니다.
이번 포스팅에선 웹 어플리케이션 성능 테스트 오픈 소스인 JMeter에 대해서 알아보겠습니다.
JMeter란?
Apache에서 만든 자바로 만들어진 웹 어플리케이션 성능 테스트 오픈 소스입니다.
JMeter를 이용해서 아래와 같은 테스트를 할 수 있습니다.
- 웹 - HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, …)
- SOAP / REST 웹 서비스
- FTP
- JDBC
- LDAP
- JMS - Message-oriented middleware (MOM)
- Mail - SMTP(S), POP3(S) and IMAP(S)
- Native commands or shell scripts
- TCP
- Java Objects
Swing으로 제작한 GUI와 CLI 방법을 지원하고 있습니다. 자세한 동작 방법은 아래에서 알아보겠습니다.
설치하기
1. Apache JMeter 다운로드 페이지 접속
2. apache-jmeter-5.4.1.zip 클릭해서 다운로드 후 압축해제
실행 방법
cmd -> 압축푼 폴더 아래 bin 폴더로 이동 -> jmeter 입력 후 엔터
아래와 같은 GUI 가 나옵니다. CLI는 아래 테스트 방법에서 알려드리겠습니다.
테스트
테스트 전 유의사항
테스트 하는 웹 어플리케이션 서버와 테스트를 돌리는 서버는 서로 달라야 합니다.
JMeter를 돌리는 서버와 웹 어플리케이션 서버가 같으면 같은 메모리를 사용하기 때문에 정확한 값을 측정할 수 없습니다.
테스트가 목적이니 저는 그냥 로컬에서 2개 같이 쓰겠습니다...
JMeter 테스트 용어
테스트 들어가기 전 JMeter 테스트 용어부터 알아보겠습니다.
- Thread Group : 테스트에 사용될 쓰레드 개수, 쓰레드 1개당 사용자 1명
- Sampler : 사용자의 액션 (예: 로그인, 게시물 작성, 게시물 조회 등)
- Listener : 응답을 받아 리포팅, 검증, 그래프 등 다양한 처리
- Configuration : Sampler 또는 Listener가 사용할 설정 값 (쿠키, JDBC 커넥션 등)
- Assertion : 응답 확인 방법 (응답 코드, 본문 내용 비교 등)
테스트 Controller
테스트할 Controller를 만들어보겠습니다. 이번 포스팅은 성능 테스트 방법에 대한 거라 최대한 간단하게 만들겠습니다.
package com.effortguy.perftest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PerfTestController {
@GetMapping("posts/{postsId}")
public String getPosts(@PathVariable Long postsId) {
return "perfTest postsId : " + postsId;
}
}
JMeter 테스트 설정
0. 테스트 생성하기
File -> New -> Test Plan Name 설정
1. Thread Group
테스트할 유저 수를 설정합니다.
0에서 만든 테스트에 오른쪽 클릭 -> Add -> Threads (Users) -> Thread Group
Action to be taken after a Sampler error에서 Error가 리턴됐을 때 어떻게 할 건지에 대한 설정을 할 수 있습니다.
Thread Properties
Number of Threads (users)
- 하나의 스레드이고 단일유저이다. 각각의 스레드는 독립된 형태로 동작한다.
Ramp-up period (seconds)
- Number of Threads 갯수만큼 도달하는데 몇 초를 사용할 것인지 정의한다. 만약 10 threads 를 설정하고 ramp-up periods 를 100 seconds 로 설정했다면, 10 개의 스레드를 모두 가용하는데 100초의 시간을 사용할 것이다. 결과적으로 10초마다 한개의 스레드가 실행된다는 의미이다.
Loop Count
- 스레드 그룹이 최대 몇번 반복할 것인지 정의한다. infinite | n 으로 값을 설정할 수 있으며 1은 Number of Threads 만큼 한번만 수행하겠다는 의미이다.
Name : 테스트 이름이다. 당연하지만 안 중요하다.Action to be taken after a Sampler error : 샘플러가 에러시에 취할 행동이다. 사실 보통 Continue를 두면 에러와 무관하게 루프를 돌게된다.Number of Threads : 쓰레드를 동시에 몇개 생성할지이다. 즉 동시에 몇개의 트랜잭션을 실행시킬지이다.Ramp-Up Period : 쓰레드를 Ramp-Up Period시간동안 실행해라는 의미이다. 단 균등하게 시간을 나눠서 실행하려고 노력한다. 예를 들어 Nomber of Threads가 10인데 Ramp-Up Period가 60이면 10개의 쓰레드가 6초간격으로 동작하려고 한다. 근데 그렇게 안될 수도 있다.
Delay Thread creation until needed : 스레드의 생성을 필요할 때까지 기다린다. 체크를 해제하면 안기다리고 날리는데 반응성은 더 좋아지긴 하는데 안정성을 위해서 체크해 두자.
Duration : Scheduler를 체크했을때만 사용가능. Thread Properties의 총작업을 하는 시간을 의미한다. 예를들어 100초를 정하면 위의 작업을 딱 100초동안 실행한다. 100초안에 걸리는 작업이면 조기에 정지되지만 위의 작업이 100초를 넘어간다면 더이상 실행하지 않고 멈춘다.
Startup delay : 위의 작업을 실행하기 위한 유예기간을 의미한다. 쓰레드 그룹이 한개일때는 별 필요없지만 쓰레드 그룹을 여러개 돌릴떄는 서로 차등을 줄 수 있다.
Scheduler : 위의 모든 작업을 스케줄화 해서 할 수 있다.
Loop Count : 스레드의 반복 횟수를 의미한다. 10이면 10번 반복한다. Forever에 체크하면 무한 반복한다.
이는 사람이 동시에 접속하는 효과를 낸다. 10명이서 동시에 접속하는 상황을 만들고 싶다면 10을 사용하면된다.
만약 다른 행동을 취하고 싶다면 해도된다.
Comments : 첨부할 설명이다. 당연하지만 안 중요하다.
10명의 유저가 1초만에 2번 반복해서 에러가 발생해도 계속 요청을 보낸다고 설정하겠습니다.
2. Sampler
1에서 사용자를 만들었으니 이제 사용자가 해야 할 행동을 정의해보겠습니다.
1에서 만든 Thread Group 우클릭 -> Add -> Sampler -> HTTP Request 클릭
위에서 만든 Controller에 요쳥을 보내는 Sampler를 만들겠습니다.
- Server Name or IP : localhost
- Port Number : 8080
- HTTP Request : Get /posts/10
3. Listener
2에서 만든 Sampler가 받아오는 리턴 값을 바탕으로 그래프, 레포팅을 만들어주는 Listener를 만들어보겠습니다.
2에서 만든 HTTP Request에 오른쪽 클릭 -> Add -> Listener -> View Results Tree, Summary Report, View Results in Table 생성
4. Assertion
응답값이 제대로 왔는지 검증을 하기위해 Assertion을 추가해보겠습니다.
2에서 만든 HTTP Request 우클릭 -> Add -> Assertions -> Response Assertion 클릭
Text Response 클릭 -> 맨 아래 Add 클릭 -> 추가된 Partters to Test 더블클릭 -> perfTest postsId 입력
위까지 1, 2, 3, 4까지 다 따라하셨으면 아래와 같이 구성됩니다.
JMeter 테스트 실행
저 버튼을 클릭하면 셋팅해놓은 설정대로 테스트가 진행됩니다.
만약 아까 만든 설정들이 적용이 안 됐다면 저 버튼을 클릭해줍니다.
아까 만든 Listener들을 쭉 보겠습니다.
View Results Tree
아까 요청을 20번 보내게 했기때문에 20개의 요청 정보가 나온 걸 볼 수 있습니다.
하나의 리퀘스트의 테스트 시작 시간, 응답 속도 등 다양한 정보들이 나옵니다.
View Result Tree 는 기존의 View Results in Table과는 다른 관점에서 보여준다.
하나하나의 데이터를 확인할 수 있으며 당연히 결과를 내보낼 수 있고 심지어 검색할 수 있다.
Response data를 클릭해보면 아까 위 컨트롤러에서 보내게했던 perfTest postsId : 10을 받았다고 나옵니다.
View Results in Table
View Results Tree를 Table 형식으로 보여줍니다. 데이터는 동일합니다.
Table 열 데이터
Sample - 그냥 ID번호다. 이 번호를 보고 몇번째로 보는 부하인지 알 수 있다.
Start Time - 보내기 시작한 시간으로 ms단위까지 나온다.
Thread Name - 쓰레드 그룹 이름
Label - 보낸 request의 이름
Sample Time(ms) - Load Time, Elapsed Time, Response Time이랑 같은 뜻이다. 요청 시작 시점부터 응답 종료 시점까지의 시간을 의미
Status - 말그대로 응답상태를 확인할 수 있다.
Bytes - 응답 데이터 바이트
Sent Byte - 요청 데이터 바이트
Latency - 지연 속도를 의미하는데 요청 시작 시점부터 응답 시작 시점까지의 시간을 의미
Connect Time(ms) - TCP Handshake를 이용해 연결하는 시간(그냥 TCP연결시간)
Table footer 데이터
No of Samples - No는 아니다라는 뜻이 아니라 number라는 뜻, 처리중인 데이터 수를 의미
Latest Sample - 가장 마지막 Sample Time
Average - 생략되있는데 Sample Time 평균
Deviation - 생략되있는데 Sample Time의 표준편차
Summary Report
참고로 모든 지표는 sample time(=load time, response time, elapsed time)를 기준으로 만든다.
Label - 우리가 사용했던 request의 이름을 기준으로 모은다. 따라서 다르게 집계하고싶다면 이름을 반드시 다르게 한다.
Samples - requset 갯수
Average - Sample Time의 평균
Min - Sample Time의 최소
Max - Sample Time의 최대
Std. Dev. - Sample Time의 표준편차
Error % - 에러율
Throughput - 분당 처리량(=쓰루풋)
Received KB/sec - 시간당(sec) 받은 데이터(KB)
Sent KB/sec - 시간당(sec) 보낸 데이터(KB)
Avg. Bytes - 서버로부터 받은 데이터 평균
View Results에 대한 통계를 나타냅니다. 통계 정보가 필요한 경우 사용하면 되겠습니다.
Aggregate Report (이건 위에서 추가하지 않았는데 새로 추가했습니다.)
- Label : Sampler 명
- # Samples : 샘플 수 (Number of Threads X Ramp-up period)
- Average : 평균 응답 시간
- Median : 응답 시간 중앙값
- 90% Line : 90%의 샘플은 해당 값보다 적은 시간 내에 끝나고 10%는 더 걸린다. 라는 뜻의 컬럼
- 95% Line : 95%의 샘플은 해당 값보다 적은 시간 내에 끝나고 5%는 더 걸린다. 라는 뜻의 컬럼
- 99% Line : 99%의 샘플은 해당 값보다 적은 시간 내에 끝나고 1%는 더 걸린다. 라는 뜻의 컬럼
- Min : 최소값
- Maximum : 최대값
- Error % : 에러율
- Throughput : 초당 처리량
- Received KB/sec : 초당 받은 KB
- Sent KB/sec : 초당 보낸 KB
Aggregate Report의 장점은 90%, 95%, 99% Line 컬럼인 거 같습니다.
90%보다 95% 컬럼을 참고하면 좀 더 정확하게 걸리는 시간을 알 수 있겠네요.
+ Response Assertion
위에서 설정한 Response Assertion이 걸리지 않아 모든 테스트가 통과했는데 통과하지 않으면 어떻게 되는지 보겠습니다.
일부러 에러를 내봤습니다. 에러가 나면 아래처럼 빨간색으로 엑스표시가 나오고 어떤 에러가 발생했는지 나옵니다.
Graph Results - 대략적으로 그래프를 쉽게 보고싶다면
그래프를 시각화해서 보여준다. 대략적으로 볼 수 있는데 필자가 많이 쓴다.
Response Time Graph - 계속적으로 추세를 보고 싶다면
이렇게 세팅을 해서 Graph탭을 누르면 추세를 볼 수 있다.
이도 꽤 괜찮은데 전체적으로 추세를 볼 수 있기 떄문이다.
추가
Sampler를 직접 설정하지 않고 BlazeMeter라는 크롬 확장 프로그램으로 행동을 녹화해 JMeter 에서 사용하는 .jmx 파일로 만들어 사용할 수 있습니다.
추후에 필요하다면 테스트해서 다시 포스팅하겠습니다.
JMeter의 수 많은 기능 중 일부만 알아봤습니다. 개발을 하면서 아직까지 저런 테스트를 해본 적이 없는데 실제로 이런 툴을 써서 테스트하는지 궁금하네요.
참고
'Oracle' 카테고리의 다른 글
[Oracle] I/O Event별 튜닝 방법(1)- db file sequential read, db scattered read, direct path read (0) | 2023.09.08 |
---|---|
[Oracle] 서브 쿼리 관련 힌트절 (no_unnest, no_merge, push_subq, push_pred) (2) | 2023.04.04 |
[Oracle] ITL과 transaction의 관계 이해 (0) | 2023.03.17 |