[작성일: 2023. 09. 06]
다양한 성능 테스트 도구
웹 성능 및 부하 테스트를 수행할 수 있는 도구에는 여러 가지가 있습니다.
- Apache JMeter
- LoadUI : 서버 모니터링, Drag&Drog 등 사용자의 편리성이 강화된 부하 테스트 도구
- OpenSTA : HTTP, HTTPS 프로토콜에 대한 부하 테스트 및 생산품 모니터링
- Scouter : Java 기반의 애플리케이션 모니터링 도구
이 중에서 플러그인이 깔끔한 JMeter를 사용해서 프로젝트 서버의 성능 테스트를 진행했습니다.
JMeter란?
Apache JMeter는 오픈 소스 소프트웨어로 기능 동작을 로드 테스트하고 성능을 측정하는데 사용되는 100% 순수한 자바 애플리케이션입니다. JMeter를 이용하면 아래와 같은 테스트를 진행할 수 있습니다.
- 웹 - HTTP, HTTPS(Java, NodeJS, PHP, ASP.NET, ...)
- SOAP / REST 웹 서비스
- FTP
- JDBC
- LDAP
- JMS - Message-orented middleware (MOM)
- Mail - SMTP(S), POP3(S) and IMAP(S)
- Native commands or shell scripts
- TCP
- Java Objects
JMeter 테스트 용어 알아보기
- Thread Group: 테스트에 사용될 쓰레드 개수, 쓰레드 1개당 사용자 1명을 의미
- Sampler: 사용자의 액션(로그인, 게시글 작성, 게시글 조회 등)
- Listener: 응답을 받아 리포팅, 검증, 그래프 등 다양한 처리
- Configuration: Sampler 또는 Listener가 사용할 설정 값(쿠키, JDBC 커넥션 등)
- Assertion: 응답 확인 방법(응답 코드, 본문 내용 비교 등)
테스트
Thread Group에서 Thread Properties는 다음과 같이 설정했습니다.
- Number of Threads (users) : 50 ➡️ 쓰레드 개수(유저 수)
- Ramp-up period (seconds) : 1 ➡️ 쓰레드를 만드는데 소요되는 시간
- Loop Conut : 2 ➡️ infinite | n 으로 값을 설정할 수 있으며 설정된 값에 따라 Number of Threads X Ramp up period 만큼 요청을 다시 보냄
50명의 유저가 1초만에 2번 반복해서 에러가 발생해도 계속 요청을 보내도록 설정했습니다.
우선 게시글 작성을 테스트 해보기 위해 다음과 같은 Sampler를 작성했습니다.
- Server Name or IP : AWS 서버 주소
- Port Number : 8080
- HTTP Request : POST / communities
- Body Data : JSON 형식으로 게시글 작성에 필요한 정보 작성
테스트 실행 후 결과를 살펴보겠습니다. (View Results, Summary Report)
Summary Report는 View Results에 대한 통계를 나타냅니다. 통계 정보가 필요한 경우 사용할 수 있습니다.
- Sample # : 샘플 실행 수 (Number of Threads X Ramp-up period)
- Average : 평균 시간(ms)
- Label : Sampler명
- Min : 최소
- Max : 최대
- Std. Dev. : 표준편차
- Error % : 에러율 (저는 처음에 사용 법을 헤매서 에러율이 조금 올라가 있는 상태입니다.)
- Througput : 초당 처리량
- Received KB/sec : 초당 받은 데이터량
- Sent KB/sec : 초당 보낸 데이터량
- Avg. Bytes : 서버로부터 받은 데이터 평균
성능 지표
성능 지표 | 설명 |
응답 시간(Response Time) | 요청을 보내고 응답을 받는 데 걸리는 시간 |
쓰레드 수(Thread Count) | 동시에 처리되는 쓰레드 또는 사용자 |
TPS (Transactions Per Second) | 초당 처리되는 트랜잭션 수를 나타내는 지표 (Throughput) |
에러율(Error Rate) | 성능 테스트 중에 발생한 오류 및 예외 비율 |
위의 성능 지표를 확인하기 위해 쓰레드 수를 100으로 지정한 후 3개의 API를 각 3분씩 테스트 진행해보았습니다.
게시글 전체 조회(GET /communities)
게시글 전체 조회 테스트 결과 오류율은 0.70%, TPS는 79.8/sec가 나왔습니다.
게시글 작성(POST /communities)
게시글 작성 테스트 결과 오류율은 0.01%, TPS는 4029.6/sec이 나왔습니다.
마이페이지(GET /mypage)
마이페이지 테스트 결과 오류율은 0.01%, TPS는 3752.2/sec가 나왔습니다.
오류율은 테스트 중지 전 모두 0.00%였으나 테스트를 중지하면서 생긴 오류로 추정됩니다.
해당 에러 메시지는 Java와 JMeter를 사용하여 요청을 처리하던 중 발생한 예외로 소켓이 이미 닫혀있음을 나타냅니다.
개인 과제: 게시글 조회와 게시글 작성의 TPS는 왜 차이가 날까?
게시글 전체 조회의 TPS는 79.8, 게시글 작성의 TPS는 4029.6이 나왔습니다.
그래서 스레드의 수를 50으로 줄이고 30초 동안 동시에 테스트를 재진행 해보았습니다.
이 전 테스트의 문제점은 게시글 작성 테스트를 선 진행하여 70만 개의 samples가 생겼습니다.
그 후 게시글 전체 조회 테스트를 진행하니 TPS가 현저히 낮아질 수밖에 없었습니다.
게시글 작성과 조회의 테스트를 동시에 진행하니 Samples와 TPS가 거의 유사한 것을 확인할 수 있었습니다. (오류율은 여전히 소켓 오류입니다.)
아래는 해당 테스트의 TPS 그래프입니다.
X축(가로축)은 시간을 의미하며 30초의 테스트 실행 시간을 나타냅니다.
Y축(세로축)은 초당 트랜잭션 수(TPS)를 의미하며 특정 시간에 성공적으로 완료도니 트랜잭션의 수를 나타냅니다.
해당 테스트의 TPS는 480~490대로 일정하게 유지되고 있었음을 확인할 수 있습니다.
개인 과제: 성능 향상을 위해 코드 수정해보기
게시글 작성 코드 중에 불필요한 로직이었던 로그인 확인 여부를 메서드로 빼고 불필요한 주석을 삭제하는 등 코드를 수정했습니다.
Samples와 TPS가 이전 테스트에 비해 2배 정도 향상되었고 응답시간도 빨라진 것을 확인할 수 있었습니다.