로그인 기능 이후 게시글과 댓글 기능까지 만들었다. 리팩토링 하기 전에 부하 테스트를 해보고 성능에 문제가 있는 것을 한 번에 리팩토링하면 좋을 것 같아 시도해 보았다.
nGrinder 삽질
아래는 nGrinder 오픈소스 링크이다. 여기서 알맞은 버전을 다운로드하여 사용해야 한다.
https://github.com/naver/ngrinder/releases
내가 그냥 최신버전 했다가 삽질을 엄청 했는데 현재 내 환경은
macOS Ventura 13.4.1
java openjdk8
을 사용했다.
openjdk8을 사용한 이유는 8 버전이 가장 잘 된다고 한다. 11도 되는 것 같지만 시도해보지 않았다.
우선 이 환경에서 nGrinder 3.5.8 버전이 되지 않아서 3.5.6 버전을 다운로드하여서 실행하니 되었다.
https://github.com/naver/ngrinder/discussions/927 3.5.8 버전은 해당 링크와 같은 문제가 생겨 계속되지 않았다..
nGrinder 깃헙에 가면 사용법도 설명이 되어있다. 그 설명을 보고도 난 잘하지 못해서 아래 링크와 같은 에러를 마주했다.
http://ngrinder.373.s1.nabble.com/controller-td3268.html
설치한 경로에 가서
sudo java -jar ngrinder-controller-3.5.6.war --port 8888
이렇게만 실행해도 된다. 포트는 위처럼 원하는 포트로 설정이 가능하다.
이거 적는 동안 3.5.6이 안되고 3.5.8이 갑자기 된다 뭐지?
뭐가 문제였는지 모르겠다..
여하튼 접속하면 아래와 같은 화면이 나온다.
초기 아이디와 비밀번호는 admin, admin이다
우측 상단 메뉴바에서 에이전트 다운로드를 클릭하여 에이전트 다운로드를 하고 압축을 푼다.
이후 압축을 해제한 에이전트 폴더로 이동한다.
./run_agent.sh
위의 명령어로 에이전트를 실행한다
실행되면 위와 같은 화면을 볼 수 있다.
실행이 정상적으로 됐다면 방금 접속한 localhost:8888의 우측 상단 메뉴바의 에이전트 관리 탭으로 넘어가서 확인할 수 있다.
이제 시작이다 테스트 스크립트 작성해서 실행하면 된다. Groovy라는 언어로 작성하는데 Junit5 기반이고 Java와 비슷하다고 해서 이곳저곳 찾아보며 작성했다.
스크립트는 왼쪽 상단에 보면 성능 테스트와 스크립트가 있다. 스크립트를 작성하고 해당 스크립트를 기반으로 성능 테스트에서 애플리케이션을 테스트하고 그 결과에 대해 조회할 수 있다.
하.. 내 프로젝트가 8 버전이 아니라 17 버전이라 안된다..
플젝 버전 바꾸려니 바꿀 게 너무 많아 다른 테스트 도구 찾아봐야겠다..
JMeter
아파치에서 만든 java기반의 오픈소스로 꽤 오래되어 안정적이라고 한다.
장점으로는 자료가 많고 다양한 프로토콜과 GUI, 이메일, DB, SSL 등 지원하는 기능과 플러그인이 많다.
단점은 모니터링이 불편하다는 것이다. nGrinder 사용하려고 한 것도 시각화가 잘 되어있어 해보려 했는데 ㅓㅇㄴ미라;ㅓㅇㄴ리ㅏ;
그리고 스레드 기반이라 성능 제약이 있다고 한다.
brew install jmeter
맥기준 위와 같이 간단하게 설치하고
open /usr/local/bin/jmeter
위의 명령어를 입력하면 실행할 수 있다.
그럼 이런 화면이 나온다. 이제 플러그인을 설치해야 한다.
Options → Plugins Manager 클릭
그럼 이런 창이 나오는데 3 Basic Graphs, Custom Thread Groups를 설치한다.
Available Plugins에 들어가서 검색해서 체크한 후 우측 하단의 Apply Changes and Restart JMeter클릭
테스트
우클릭해서 Thread Group생성하고 Thread Group우클릭해서 HTTP Request생성
Thread Group → Listener에서 View Results Tree, Summary Report, Transaction Per Second를 추가한다.
Thread Group을 눌러서 필요한 세팅을 해준다.
Number of Threads
가상의 생성자를 몇 명으로 설정할 것인지에 대한 값이다.(몇 개의 스레드를 생성할 것인지) 이 값이 커지면 부하가 커질 것이다.
Ramp-up Period
하나의 실행을 몇 초 동안 완료 시킬지에 대한 값이다.
Loop count
반복 횟수로 infinite를 클릭하면 무한으로 실행한다.
Action to be taken after a Sample error는 에러 처리가 되었을 때 행동하는 것이다. Assertion의 결과로 판단한다.
다음으로 HTTP Request이다 여기는 Web Server부분을 설정하면 된다.
Header 추가를 위해 Thread Group → Add → Config Element → HTTP Header Manager 추가하면 아래와 같은 화면을 볼 수 있다.
실제 요청에 보낼 헤더 설정을 해주면 된다.
Listener는 이것저것 추가해 보며 필요한 것들 사용하면 좋을 것 같다.
나는 로그인을 토큰으로 해서 토큰 관리도 해줘야 한다. 로그인에서 받은 응답의 토큰을 사용할 수 있게 하는 설정이다.
accessToken만 받아와서 사용할 것이다.
JSON Path expressions로 어떤 데이터를 가져올지 추출해야 한다. 나의 경우 실제 응답은 아래와 같다.
예시를 보면 아마 다들 따라 할 수 있을 것이라 생각한다.
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
이후 HTTP Header Manager에 ${accessToken}과 같이 추가하면 된다. 이때는 JSON Extractor에 Named of created variables에 선언한 변수명을 ${} 안에 넣으면 되는 것이다.
우선 300개로 로그인과 검색만 돌려본 요약 보고서이다.
총 600개의 요청과 Average, Min, Max의 단위는 ms단위이다. 의외로 로그인이 약 0.4초, 리스트 조회가 약 0.1초 정도로 로그인이 시간이 오래 걸리는 것을 확인할 수 있다. 300개까지 돌렸을 때 Error는 없었다.
Throughput은 처리량을 의미한다(Transaction Per Second)
데이터가 적은 것 같아 테스트용 데이터베이스에 게시글과 10000개와 그 게시글에 각각 댓글 10개씩 넣어서 테스트를 해보았다. 처음에 댓글도 500개 넣으려다 컴퓨터 터지는 줄;
그리고 동시 사용자는 1000명으로 설정하고 테스트를 했다.
원하는 리스너를 등록해서 위오 같이 다양하게 시각화할 수 있다.
결과를 보니 확실히 데이터가 많은 게시글 조회에 시간이 오래 걸린다. 그리고 생각보다 로그인 과정이 오래 걸린다.
Start Time - 보내기 시작한 시간으로 ms단위까지 나온다.
Thread Name - 스레드 그룹 이름
Label - 보낸 request의 이름
Sample Time(ms) - 요청 시작 시점부터 응답 종료 시점까지의 시간을 의미한다.
Status - 응답 상태
Bytes - 응답 데이터 바이트
Sent Byte - 요청 데이터 바이트
Latency - 지연 속도를 의미하는데 요청 시작 시점부터 응답 시작 시점까지의 시간을 의미
Connect Time(ms) - TCP Handshake를 이용해 연결하는 시간(그냥 TCP연결시간)
그리고 하단에 보면
No of Samples - No는 아니다는 뜻이 아니라 number라는 뜻, 처리 중인 데이터 수를 의미
Latest Sample - 가장 마지막 Sample Time
Average - Sample Time 평균
Deviation - Sample Time의 표준편차
아래는 500명 사용자가 200번의 요청을 반복하는 것이다.
aggregate report를 추가해 봤는데 99% Line 이게 99%의 샘플은 해당 값보다 적은 시간 내에 끝나고 1%는 더 걸린다는 의미라고 한다. 95,90도 마찬가지이다. 대부분 1초 안에 응답을 했다.
컴퓨터 터질 정도로 테스트를 해보고 싶지만 로컬 환경이라 못하겠다.. 우선 게시글 리스트 조회 부분을 조금 수정할 예정이라 해당 기능을 수정을 할 것이다. 추가로 의존성 관리가 잘 안 되는 부분이 있어 해당 부분을 개선하고 이후에 다시 JMeter를 사용해서 테스트 후에 성능 개선을 위한 작업을 해봐야겠다. 그리고 성능 개선 전과 후 비교를 해보면 개선을 위해 했던 작업들이 왜 필요한지 몸으로 체감할 수 있을 것 같다.
'Java > Spring boot 프로젝트' 카테고리의 다른 글
[리팩토링 3] 쿼리 수정 및 최적화와 JMeter를 사용한 비교-게시판 만들기(16) (0) | 2023.08.09 |
---|---|
[리팩토링 2] 의존성 관리하기 -게시판 만들기(15) (0) | 2023.08.09 |
@EntityListener로 생성일, 수정일 자동으로 넣기 + 프록시 활용(연관관계 Insert) - 게시판 만들기(13) (0) | 2023.06.29 |
Spring Security + JWT 적용하기(3) - 게시판 만들기(12) (0) | 2023.04.15 |
Spring Security + JWT 적용하기(2) - 게시판 만들기(11) (0) | 2023.04.06 |