서버의 성능을 최적화하기 위해선 어떤 작업이 필요할까요?
어떤 지표를 기준으로 성능을 측정할 것인지,
정의된 지표에 영향을 미치는 변수에는 무엇이 있는지,
해당 변수들의 변화가 성능에 미치는 영향은 어느 정도인지 등 많은 작업이 필요할 것입니다.
그 중에서도 반복해서 요청을 발생시킴으로써 지표를 측정할 수 있게 해주는 테스트 도구는 필수 불가결합니다.
이번 포스팅에선 Apache JMeter를 이용해 부하를 발생시키고, 그 결과를 리포트로 생성해보겠습니다.
부하 테스트를 위한 도구들
어떤 부하 테스트 도구를 사용할까요?
주변에서 가장 많이 접했던 k6, nGrinder, JMeter 세 가지를 고민했습니다.
처음엔 성능 측정을 위해 어떤 지표가 필요하고, 각 도구가 어떤 지표를 제공하는지 등을 고려했는데요
필요한 지표들을 대부분 충분히 제공하고, 모니터링은 그라파나를 사용할 예정이다보니 필수는 아니었습니다.
최종적으로는 JMeter를 선택했는데요, 릴리즈된지 가장 오래된 프로젝트이면서도
최근까지 유지보수가 이어져오고 있어서 방대한 커뮤니티가 있다는 점이 장점이었습니다.
또한 설치와 사용방법이 가장 간단하다는 점을 꼽을 수 있습니다.
마지막으로, JMeter가 자동으로 생성해주는 HTML 형식의 보고서의 제공 기능이 매력적으로 다가왔습니다.
요약하자면 제가 느낀 JMeter의 타 도구 대비 장점은 아래의 세 가지로 요약됩니다.
- 설치, 사용하기 쉬움
- 커뮤니티, 레퍼런스 방대하고 최근까지도 유지보수 진행됨
- HTML 형식의 보고서가 풍부한 정보를 제공해줌
관련해서 k6 공식 홈페이지에 JMeter와 k6를 비교한 글이 있어 소개합니다.
무조건 가장 좋은 도구라는 것은 있을 수 없고, 상황에 맞는 도구가 있으니,
이럴 땐 JMeter를, 이럴 땐 k6를 고려해보라 라는 취지의 글인데요,
아주 친절하고 상세하면서도 중립적인 포지션에서 쓰여진 글이라서..
k6에 대한 신뢰도가 상당히 올라가게 해준 글이었습니다 👍
JMeter의 설치와 실행
1분이면 설치부터 실행까지 가능합니다!
공식 홈페이지에서 zip 파일을 다운받습니다.
압축을 풀면 bin 폴더에 jmeter.sh 파일과 jmeter.bat 파일이 있습니다.
맥에선 sh파일로, 윈도우에선 bat파일을 실행하면 됩니다.
별다른 설정을 하지 않았는데 처음부터 한글로 실행되었습니다.
간단하게 설치와 실행이 완료되었습니다.
(brew를 사용하신다면 brew install jmeter 를 사용할 수 있습니다.)
JMeter의 구성요소
JMeter를 본격 사용하기 전에, 간단히 살펴보고 갈까요?
Jmeter의 구성요소를 간단히 알아보겠습니다!
가장 위에 있는 Thread Group은 쓰레드들을 관리하는 곳입니다.
여기에서 쓰레드 수, 즉 가상의 사용자 수를 설정할 수 있습니다.
1000명의 사용자가 동시에 접속한다 라는 테스트 환경을 쓰레드 그룹에서 쓰레드 숫자를 조정함으로써 설정할 수 있습니다.
두번째 줄 첫번째에 있는 Samplers는 요청을 추상화한 것이라 볼 수 있습니다.
FTP, HTTP, SMPT 등 다양한 요청 유형을 선택할 수 있습니다.
이번 포스팅에선 HTTP 요청만 진행할 예정입니다.
두번째 줄 두번째에 있는 Logic Controller는 요청들을 묶어서 시나리오화한 것으로 볼 수 있습니다.
가령 하나의 Logic Controller에 여러 HTTP 요청 Samplers들을 순차적으로 담음으로써
사용자의 실제 사용 예상 시나리오와 유사하게 테스트 환경을 구성할 수 있습니다.
두번째줄 세번째에 있는 Listeners는 테스트 결과를 추상화한 것이라 볼 수 있습니다.
그래프, 테이블 등 여러 형태로 테스트 결과를 시각화해줍니다.
두번째줄 네번째의 Configuration Elements 는 테스트 환경에 적용될 설정입니다.
가령 HTTP 요청 Sampler를 이용한 테스트를 할 때, 헤더에 토큰을 담거나, 쿠키에 세션을 담음으로써
로그인된 사용자의 요청으로 만들기 위한 쿠키, 헤더 값을 설정할 수 있습니다.
테스트 환경에 사용되는 주요한 요소들에 대해서만 알아봤습니다.
앞서 언급한 Thread Group, Samples, Logic Controllers, Listeners, Congiruation Elements 등을
모두 JMeter 내에선 Element라고 부릅니다.
이제 대략적인 구성요소까지 알아봤으니, 실제 테스트를 구성하고 실행해봅시다!
첫 테스트 만들기
JMeter는 GUI를 제공해주기 때문에 손쉽게 테스트를 구성할 수 있습니다!
- 테스트 계획 우클릭 -> 추가 -> 쓰레드들 -> 쓰레드 그룹을 선택하여 쓰레드 그룹을 생성합니다.
- 쓰레드 그룹 우클릭 -> 추가 -> 표본추출기(Sampler) -> HTTP 요청을 선택하여 샘플러를 하나 생성합니다.
- 현재 개발중인 프로젝트 개발 서버에 있는 백엔드 API를 호출해보겠습니다.
- GET https://dev.myrss.ga/api/feeds 요청은 최신 피드 20개를 응답하는 엔드포인트입니다.
- 이미지처럼 몇가지 내용만 입력해주면 GET요청을 보낼 준비가 완료되었습니다.
- 앞서 생성했던 쓰레드 그룹을 클릭해서 설정해봅시다
- 쓰레드들의 수는 가상 사용자를 몇 명으로 설정할지를 의미합니다.
- Ramp-up 시간은 쓰레드 수들을 얼마 시간 동안 테스트할지에 대한 설정입니다.
- 가령 쓰레드 수에 100, Ramp-up에 10을 입력하면 1초에 10번씩 요청이 전송됩니다.
- 부하 테스트 목적이므로 저는 1로 그대로 두겠습니다.
- 자세한 내용은 공식 문서를 참고하시면 도움이 될 것 같습니다.
- 루프 카운트는 사용자들이 몇번 요청할지 설정합니다.
- 가령 쓰레드 100, 루프 카운트 10이면, 100명이 10번씩 요청해서 총 1000번의 요청이 전송됩니다.
- 무한을 체크하면 중단할 때까지 전송됩니다.
- 이번엔 1로 두고 진행해보겠습니다.
여기까지, 테스트 환경 설정이 완료됐습니다!
리스너 만들기
테스트 수행 결과를 쉽게 살펴볼 수 있게 해주는 리스너를 만들어봅시다!
쓰레드 그룹 우클릭 -> 추가 -> 리스너 -> 결과들의 트리 보기, 요약 보고서, 결과 그래프
- 결과들의 트리 보기
- 요약 보고서
- 결과 그래프
위와 같은 총 세 가지의 리스너를 생성했습니다.
각 리스너의 표현 방식은 테스트 수행 이후에 하나씩 소개해보겠습니다.
테스트 실행하고 리스너로 결과 확인
상단에 있는 초록색 버튼을 눌러서 테스트를 실행할 수 있습니다.
구성한 테스트 계획을 저장할지 물어보는 팝업이 나오는데요, 저는 우선 아니오를 누르고 계속 진행하겠습니다.
테스트가 시작되면 우측 상단에 테스트 수행 타이머와 액티브 쓰레드 숫자가 표기됩니다.
100개의 쓰레드가 1번씩 요청을 전송하기 때문에, 액티브 쓰레드 숫자가 100까지 올라갔다가,
다시 0으로 내려오는 모습으로 나타났습니다.
이제 결과를 확인해보죠.
요약 보고서
- 요약 보고서입니다.
- 총 100번의 요청이 수행됐습니다. 평균, 최소, 최대는 ms단위입니다.
- 따라서 평균적으로 0.9초 정도의 응답시간이 소요되었음을 알 수 있습니다.
- 오류 0%는 HTTP 응답 코드로 판단합니다. 예외에 해당하는 400번대 또는 500번대 응답이 없었음을 예상할 수 있습니다.
- 처리량은 Throughput입니다. Transaction Per Second를 의미하는 TPS라고도 합니다. 48 TPS가 측정되었네요.
결과들의 트리 보기
- 브라우저 개발자 도구의 네트워크 탭을 본다고 생각하시면 될 것 같습니다.
- 개별 요청에 대한 요청, 응답 정보를 확인할 수 있습니다.
- 응답 body까지 확인할 수 있습니다.
결과 그래프
- 테스트 결과를 그래프 형태로 확인할 수 있습니다.
- 쓰레드 그룹에서 반복 횟수를 무한으로 했을 경우, 실시간으로 그래프의 변동을 확인할 수 있습니다.
쿠키 설정을 이용한 로그인 상태 테스트 구성
로그인 상태에서 정상 처리 가능한 요청에 대한 테스트를 구성해봅시다
토큰을 이용한 인증 인가는 헤더에, 세션을 이용한 인증 인가는 쿠키에 인증 정보를 담아 전송합니다.
따라서, HTTP 요청 샘플러를 통한 테스트 시에 이러한 정보를 함께 전송할 수 있다면
로그인 된 사용자에 대해서만 가능한 테스트를 구성할 수 있을 겁니다.
이때 사용되는 JMeter Element가 Configuration Elements 입니다.
제가 현재 테스트 중인 프로젝트는 세션을 이용한 인증 인가를 선택했기에
쿠키 설정을 추가하기 전과 후를 비교해보도록 하겠습니다.
(헤더 설정 추가 방법도 거의 유사합니다.)
로그인 정보 확인 요청 샘플러 추가
AS-IS
- 쿠키로 전송된 세션 정보가 없기 때문에 로그인 상태는 false로 응답되고 있습니다.
- 요청 정보를 보면 쿠키가 없습니다.
쿠키 설정하기
- 로그인 상태 요청 샘플러를 우클릭하고, 추가 -> 설정 엘리먼트 -> HTTP 쿠키 관리자를 생성합니다.
- 하단의 추가 버튼을 누르고 쿠키 정보를 입력합니다.
- 구성이 완료됐습니다. 이제 로그인 상태 확인 요청이 전송될 때 쿠키 정보도 함께 전송됩니다.
TO-BE
- 로그인 상태가 true로 응답되었고, 로그인한 회원의 정보도 함께 응답된 모습입니다.
- 요청 정보를 보면 쿠키에 SESSION ID가 함께 전송되었음을 확인할 수 있습니다.
쿠키 설정 위치에 따른 차이
HTTP 쿠키 관리자의 depth의 차이가 느껴지시나요? ㅎ
위 이미지처럼 구성하게 되면 로그인과 비 로그인 상태를 구분하여 테스트가 가능해집니다.
HTTP 쿠키 관리자가 있는 HTTP 샘플러만 쿠키 정보가 함께 전달됩니다.
아래 이미지처럼 구성하게 되면 해당 쓰레드 그룹 내에 있는 모든 HTTP 요청 샘플러에
쿠키 정보가 전달되게 됩니다.
이렇게 되면 HTTP 쿠키가 쓰레드 그룹별로만 구분되는 것이죠.
HTTP 쿠키 관리자의 depth에 따라 어느 영역까지 적용되는지 확인하고 사용하시면 더욱 유용할 듯 하네요.
테스트 리포트 생성하기
테스트 결과를 이용해 근사한 테스트 리포트를 생성해봅시다!
시나리오에 따른 쓰레드 그룹 설정
사용자 100명이 10번씩 요청을 발생시키는 시나리오를 가정해보겠습니다.
쓰레드는 100, 루프는 10을 줬습니다.
Ramp-up은 0을 줬는데요,
1을 주게 되면 1초 동안 100개 이상의 요청을 전송할 수 있더라도 100까지만 전송하게 되기에 0으로 설정했습니다.
테스트 결과 출력 설정
리스너로 만들어 두었던 요약 보고서 설정화면에서
파일 선택을 클릭하고 결과를 출력할 경로와 파일명을 설정합니다.
저는 JMeter 설치 폴더 내로 설정해봤습니다.
파일명은 자유롭게 하시되, 확장자를 csv로 변경해줍니다.
열기를 눌렀을 때 오류 팝업이 나와도 괜찮습니다. 확인을 눌러주시고,
파일 이름에 경로가 잘 입력되었음을 확인하면 됩니다.
이전 테스트 이력 제거 및 테스트 실행
캡쳐 상 가장 오른쪽에 있는 버튼을 눌러 이전 테스트 이력을 제거합니다.
그리고 테스트 실행 버튼을 눌러 테스트를 수행합니다.
그러면 앞서 지정했던 경로에 테스트 결과 파일이 생성됩니다.
HTML 보고서 생성
- 도구 - HTML 보고서 생성 메뉴를 클릭합니다.
- 앞서 생성해둔 csv파일과, bin폴더 내에 있는 jmeter.properties 파일을 선택해줍니다.
- 출력 디렉토리는 빈 디렉토리를 지정해줘야만 합니다. 편한 경로 내에 없는 폴더명을 작성해주면 됩니다.
- 보고서 생성 버튼을 누르면 보고서가 생성됩니다.
HTML 보고서 살펴보기
- HTTP 요청 샘플러 별 가장 빠른 응답부터, 가장 느린 응답까지 그래프로 시각화해준 모습입니다.
- 로그인 상태 확인 요청은 가장 느린 요청과 가장 빠른 요청의 편차가 심하지 않음을 알 수 있습니다. 가장 느려도 500ms 이내니까요.
- 피드 조회 요청은 빠르면 250ms 도 걸리지 않지만, 느리면 2500ms까지 소요됐네요. 100개 스레드에서 이정도 차이면 큰 차이가 발생했다고 보입니다.
- 활성 스레드 수에 따른 응답시간을 보여주는 그래프입니다.
- 쓰레드 수 0에서 100까지 가로축인데요, 100개 정도까지는 쓰레드 수에 따른 응답시간 차이가 있다고 보긴 어려워 보이네요.
- 그렇다면 쓰레드를 좀 더 늘려서 테스트해봐도 좋겠습니다.
- TPS를 시계열 그래프로 보여줍니다.
- 다만 단위가 분 단위여서 1분 이내에 테스트가 종료될 경우 점으로만 표기될 수 있습니다.
- 위 그래프는 그래서 앞서 가정한 시나리오와 다른 시나리오로 생성하여 첨부하였습니다.
- 짧게 종료되는 테스트의 TPS 그래프를 확인하기에는 HTML 보고서 보다 결과 그래프 리스너가 적절한 것 같습니다.
CLI로 테스트하기
./bin/jmeter -n -t [jmxfile].jmx -l [logfile].jtl -e -o [loadtest result path]
./bin/jmeter -n -t ./bin/221006-test-configuration2.jmx -l ./221006-test-log.jtl -e -o ../221006-load-test-cli
GUI에서 테스트 계획 설정을 마쳤다면 저장 버튼을 눌러 jmx파일로 저장해둡니다.
이 jmx파일이 있으면 CLI로 부하테스트를 수행할 수 있습니다.
위 명령어를 이용하면 테스트 버튼을 눌러 수행했던것과 마찬가지로 테스트를 수행하고,
HTML보고서를 지정한 경로에 자동 생성해줍니다.
이제 부하 테스트를 할 준비가 되었으니,
모니터링 툴을 준비한 뒤에 테스트 -> 모니터링 -> 설정 변경 을 반복해야겠군요!
학습 출처
'Server & Infra' 카테고리의 다른 글
확장 가능한 알림 시스템 설계 구상 (2) | 2022.10.07 |
---|---|
'Reveal2021 - 쿠팡의 대규모 트래픽을 다루는 백앤드 전략'을 보고 (2) | 2022.10.07 |
AWS 의도하지 않은 요금 환불받기 (2) | 2022.09.29 |
AWS CloudWatch 구축기 (EC2를 On-Premise로) (0) | 2022.09.29 |
Jenkins, Multibranch-pipeline을 이용한 CD (0) | 2022.09.10 |