Testing/성능부하테스트

Artillery

anodos 2023. 12. 27. 17:39

 

Artillery

Artillery는 간편하게 사용할 수 있는 기능과 유연성을 제공하여 개발자가 애플리케이션을 효과적으로 테스트할 수 있는 오픈 소스 라이브러리입니다.

 

공식 홈페이지에서 아래와 같은 특징들을 살펴볼 수 있습니다.

  • HTTP, Socket.io, Websocket, gRPC 등 다양한 프로토콜 지원
  • 클라우드 규모에서의 테스트 가능 (AWS Lambda 서버리스 로드 테스트)
  • HTML, JSON 등 가독성이 좋은 처리량 및 통계 제공
  • 시나리오 단위로 테스트 가능

설치 방법은 간단합니다.

라이브러리를 설치하고, artillery version 으로 설치된 것을 확인할 수 있습니다. artillery dino 라는 이스터에그 명령어로 공룡도 확인할 수 있네요. 🦕

설치가 완료되었다면 기본적인 테스트 파일을 작성해봅니다. json파일 또는 yaml 파일로도 작성할 수 있는데, 저는 yaml 파일로 진행했습니다.

루트 경로에 test.yaml 생성

기본적인 형태의 test.yaml 파일입니다.

  • target : 요청 baseURL
  • duration : n초동안 테스트
  • arrivalRate : 초당 n회의 요청
  • scenarios : 하나 이상의 테스트가 포함될 수 있는 시나리오 구성

테스트할 요청 메서드와 headers, body 값 등을 익숙한 yaml 파일로 쉽게 구성할 수 있습니다.

대기를 등록하는 요청의 yaml 파일을 각색해 작성했습니다.

 

작성이 완료되면 artillery run test.yaml -o ./results/test.json명령어로 테스트를 진행합니다.

-o ./results/test.json 옵션은 해당 경로에 테스트 결과 test.json 파일을 생성합니다.

Test

(테스트에 앞서, 개발 환경 서버의 스펙이 최소한으로 설정되어있으므로 과부하가 걸리는 요청량이 많지 않을 수 있음을 알립니다.)

테스트를 실행하면 아래와 같은 테스트 결과 지표가 출력됩니다.

 

 

먼저 duration: 10, arrivalRate: 1 값으로 단일 latency 값을 확인했습니다.


단일 요청 시 response_time.median 응답 평균 소요 시간이 156ms 인 것을 확인할 수 있습니다.

  • http.codes.200: 상태 코드가 200(OK)인 HTTP 응답 수
  • http.request_rate: 초당 HTTP 요청 수
  • http.requests: 총 HTTP 요청 수
  • http.response_time: 최소, 최대, 중앙값, 95번째 백분위수  99번째 백분위수 응답 시간을 포함한 HTTP 요청의 응답 시간에 대한 통계
  • http.responses: 수신된 총 HTTP 응답 수
  • vusers.completed: 테스트를 완료한 총 가상 사용자 수
  • vusers.created: 테스트 중에 생성된 총 가상 사용자 수
  • vusers.created_by_name: test.yaml 파일에 정의된 각 시나리오에 대해 생성된 가상 사용자 수
  • vusers.failed: 테스트 중 실패한 총 가상 사용자 수
  • vusers.session_length: 최소, 최대, 중앙값, 95번째 백분위수 및 99번째 백분위수 세션 길이를 포함하여 가상 사용자의 세션 길이에 대한 통계

 

 

이 중 가장 많이 지표로 사용되는 필드는 response_time  median 값과 95 백분위수 값인 p95입니다.

 

 

이번엔 duration: 10, arrivalRate: 10 으로 초당 10회의 요청을 테스트했습니다.

 

 response_time.median 응답 평균 소요 시간이 약 7557ms로 매우 느린 응답을 보였습니다.

 

또한 과부하로 인해 총 100건의 요청 중 vusers.failed 실패한 가상 테스트 사용자 수가 56건이나 발생한 것을 확인할 수 있습니다.

 

이번엔 duration: 10, arrivalRate: 3로 10초간 초당 3회의 요청을 진행해봤습니다.

총 30회 요청 중 실패건 없이 정상적으로 처리된 것을 확인할 수 있습니다.

 

response_time.median 값도 561ms 로 양호하네요!

그렇다면 10초간 초당 4회의 요청도 진행해볼까요?

 

duration: 10, arrivalRate: 4 로 10초간 초당 4회의 요청입니다. 실패건은 없었으나 response_time.median 응답 평균값이 3752ms 정도로 다소 많이 늘어난 것을 확인할 수 있습니다.

 

아마 duration 을 늘려 요청을 더 오래 지속한다면 fail 건도 발생할 것이 예상됩니다. 궁금하니 한번 테스트 해볼까요?

 

duration: 60, arrivalRate: 4 로 60초간 초당 4회의 요청입니다. vusers.failed 건은 발생하지 않았으나, 내부 로직에서 지연이 발생되어 500 에러가 7건 발생한 것을 확인할 수 있었습니다.

 

예를 들어 테스트할 API에 트랜잭션 1과 트랜잭션 2가 함께하는 경우, 트랜잭션 1에서 500 에러가 발생하더라도 후속 트랜잭션 2가 통과되어 실패한 가상 사용자 수에 집계되지 않을 수 있습니다.

 

이는 테스트에서는 요청 스크립트가 성공적으로 완료되었지만, 실제 유저는 500 에러의 영향을 받을 수 있다는 뜻입니다.

사용자 경험을 정확하게 반영하기 위해서는 응답 실패 건수 뿐만 아니라 오류 발생 건수도 고려하는 것이 중요합니다.

 

Artillery Graph

추가적으로 저장된 테스트 결과 test.json 을 그래프화 할 수 있는 명령어도 제공합니다.

 

테스트 결과를 간편하게 그래프 UI 로 확인할 수 있습니다. http_response.median 중앙값과 http_response.p95 백분위 95 값에 큰 격차가 없어야 성능이 좋다고 볼 수 있으니, 그래프를 통해 좀 더 쉽게 격차를 비교해 볼 수도 있을 것 같네요.

Recap

테스트를 직접 진행하면서 느껴본 Artillery의 장점을 정리해봤습니다.

  • 테스트 시나리오를 통한 단계적 테스트 가능
  • 쉽고 빠르게 yaml 또는 json 파일로 테스트 파일 작성 가능
  • 식별하기 용이한 Report Graph
  • 많은 수의 사용자와 트랜잭션 시뮬레이션을 통한 병목 현상 캐치 가능

(단일 API 요청 뿐만이 아니라 시나리오 내부에 여러 개의 API 요청을 단계별로 테스트 해보고 싶다는 궁금증도 생겼습니다!)

 

 

실제 업무에서는 테스트 서버이지만 데이터를 1000 개씩 생성하는 API 전송이 불안해서 요청 당 2초 정도의 딜레이를 두고 생성을 진행했습니다. 그러다 보니 여러 개 매장의 데이터 생성 완료까지 약 60분 정도의 시간이 소요되었는데, 테스트를 먼저 진행해 안정적인 요청 범위를 확인했다면 처리에 절반 이상의 시간을 절약할 수 있었을 터라 아쉬움이 남습니다.

앞으로는 위와 같은 대량의 데이터 요청이 들어온다면 테스트를 선행해 효율적으로 시간을 절약할 수 있을 것 같습니다.

 

 

이전 버전에서는 latency에 관한 지연율 그래프까지 제공해 주기도 했는데 pro 버전으로 전환된 건지 해당 기능은 더 이상 제공되지 않았습니다.

 

또, K6 같은 테스트 툴은 지정한 시간 내에 서버가 최대 몇 회를 처리할 수 있는지에 대한 측정이 가능합니다.

 

하지만 Artillery는 지정한 요청 횟수만큼만 테스트하고 해당 처리가 얼마만큼의 처리 시간을 요하는지에 대해서만 측정합니다.

 

이 부분이 조금 아쉬웠으나, 제가 필요한 테스트의 목적에는 맞았던 도구라 테스트할 목적에 따라 도구를 달리 선택하면 훨씬 효율적일 것이라 생각됩니다.

 

출처 :  https://techblog.tabling.co.kr/artillery%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%B6%80%ED%95%98-%ED%85%8C%EC%8A%A4%ED%8A%B8-9d1f6bb2c2f5

반응형