회사에서 프로모션성 페이지를 Nextjs를 활용하여 개발했는데 릴리즈 하자마자 메모리 부족으로 서버가 죽게 되버린 사건이 있었다. 이제는 프론트엔드 개발자도 서버를 관리 해야하는 임무를 받은 시대가 됨으로써, 어떻게 하면 안전하게 서버를 운영해볼 수 있을까 조사해보다 알게된 Artillery이라는 서버 부하 테스트 오픈소스에 대해 작성해보려 한다.
특징 및 설치방법
artillery는 다음과 같은 특징을 갖고 있다.
- 클라우드 네이티브 분산 부하 테스트를 대규모로 바로 사용할 수 있는 무료 서비스이다.
- AWS Lambda 또는 AWS Fargate에서 서버리스 부하 테스트도 가능하다.
- [HTTP], [WebSocket], Socket.io, gRPC, Kinesis 등도 지원한다.
- Artillery에는 플러그인 API도 있고 오픈소스이기 때문에 확장이 용이하다.
- 시나리오 단위로 테스트도 가능하다.
설치 및 실행방법은 간단하다.
$ npm install -g artillery@latest
먼저 위 명령어로 artillery를 설치해주고,
config:
# This is a test server run by team Artillery
# It's designed to be highly scalable
target: http://asciiart.artillery.io:8080
phases:
- duration: 60
arrivalRate: 1
rampTo: 5
name: Warm up phase
- duration: 60
arrivalRate: 5
rampTo: 10
name: Ramp up load
- duration: 30
arrivalRate: 10
rampTo: 30
name: Spike phase
# Load & configure a couple of useful plugins
# https://docs.art/reference/extensions
plugins:
ensure: {}
apdex: {}
metrics-by-endpoint: {}
apdex:
threshold: 100
ensure:
thresholds:
- http.response_time.p99: 100
- http.response_time.p95: 75
scenarios:
- flow:
- loop:
- get:
url: "/dino"
- get:
url: "/pony"
- get:
url: "/armadillo"
count: 100
간단한 테스트 스크립트를 작성해준다. 테스트 스크립트를 자세히 살펴보자.
config, scenarios
Artilliery의 테스트 스크립트는 config와 scenarios 두 부분으로 구성되어 있다.
config는 로드 테스트 실행 방법(예: 테스트 중인 시스템의 URL, 생성되는 부하량, 사용할 플러그인 등)을 정의하는 부분이다.
scenarios는 Artillery에서 생성한 가상 사용자가 수행할 작업을 정의하는 곳이다. 시나리오는 일반적으로 앱에서 사용자 세션을 설명하는 일련의 단계이다.
target
target: "http://asciiart.artillery.io:8080"
위 스크립트는 모든 요청이 해당 URL을 기본적으로 사용하도록 target을 지정해주는 부분이다.
phases
phases:
- duration: 60
arrivalRate: 5
rampTo: 10
name: Warm up the API
- duration: 60
arrivalRate: 10
rampTo: 50
name: Ramp up to peak load
- duration: 300
arrivalRate: 50
name: Sustained peak load
이 테스트에서는 세 가지 단계로 정의했는데,
- API Warm up 단계 - 이 단계는 60초 동안 실행된다. Artillery는 초당 5명의 새로운 가상 사용자를 생성하는 것으로 시작하여(
arrivalRate
) 단계가 끝날 때까지 점차적으로 초당 10명(rampTo
)의 새로운 가상 사용자까지 늘린다. - Ramp up to peak load 단계 - 이 단계도 60초 동안 지속된다. Artillery는 초당 10명의 가상 사용자에서 50명의 가상 사용자로 부하를 계속 증가시킨다.
- Sustained peak load 단계 - 이 단계는 300초 동안 실행된다. 이 단계에서는 Artilliery가 매초 50명의 가상 사용자를 새로 생성한다.
이 단계에서는 짧은 시간 동안 API의 부하가 높은 수준으로 치솟는 '스파이크 테스트'가 발생한다. 뉴스레터 발송, 깜짝 세일 등과 같은 최고치 수준의 트래픽 상황 예시라고 볼 수 있다.
plugins
plugins:
ensure: {}
apdex: {}
metrics-by-endpoint: {}
테스트의 모든 URL에 대한 세부 지표를 생성하고 테스트 결과에 대한 자동 성공 검사를 설정하기 위해 몇 가지 기본 제공 플러그인을 로드한다. 현재 예시에서는 사용하지 않는다.
scenarios
scenarios:
- name: Get 3 animal pictures
flow:
-loop:
- get:
url: "/dino"
- get:
url: "/pony"
- get:
url: "/armadillo"
count: 100
시나리오 섹션에서는 하나의 시나리오를 정의한다. 이 테스트에서 생성된 각 가상 사용자는 이 시나리오를 실행하게 된다.
시나리오는 세 단계로 구성되어 있으며, 각 단계는 다른 엔드포인트에 대한 HTTP GET 요청으로 되어있다. count
와 loop
를 사용하여 이 세 가지 요청을 100회 반복한다.
시나리오를 실행하는 모든 가상 사용자는 동일한 시나리오를 실행하는 다른 가상 사용자와 완전히 독립적이라고 볼 수 있다. 가상 사용자 간에 메모리, 네트워크 연결, 쿠키 또는 기타 상태가 공유되지 않는다.
테스트 실행
이제 테스트 스크립트에 대해 알았으니 실행해보자.
artillery run asciiart-load-test.yml
위 명령어를 실행하면 아래와 같은 부하테스트 결과 리포트를 10초마다 출력해준다.
리포트 지표 중 일부는 이름을 보고 의미를 유추할 수 있을텐데 한번 몇 가지만 알아보자.
- http.codes.200: 이 지표에서 HTTP 응답 코드에 대해 볼 수 있는데 오른쪽 숫자는 해당 기간 동안 200인 HTTP 응답수가 몇 번이였는지를 알려준다.
- http.downloaded_bytes: 이 기간 동안 다운로드된 데이터의 총 크기(바이트)이다.
- http.request_rate: 이 기간 동안 초당 평균 HTTP 요청 속도이다.
- http.requests: 이 기간 동안 이루어진 총 HTTP 요청 수이다.
- http.response_time: 이 지표는 HTTP 요청의 응답 시간(밀리초)에 대한 통계를 제공한다.
- min: 가장 짧은 응답 시간
- max: 가장 긴 응답 시간
- mean: 평균 응답 시간
- median: 정렬된 응답 시간들의 중간 값
- p95: 95번째 백분위수 응답 시간으로 응답 시간의 95%가 이 값보다 낮음을 의미한다.
- p99: 99번째 백분위수 응답 시간으로 응답 시간의 99%가 이 값보다 낮음을 의미한다.
- vusers.completed: 실행을 완료한 가상 사용자 수
- vusers.created: 이 기간 동안 생성된 총 가상 사용자 수
위 캡쳐화면에는 안나와있지만 다음과 같은 지표도 제공한다.
- vusers.session_length: 가상 사용자의 세션 길이(밀리초)에 대한 통계를 제공한다.
- min: 가장 짧은 세션 길이
- max: 가장 긴 세션 길이
- mean: 평균 세션 길이
- median: 정렬된 세션 길이 목록의 중간 값
- p95: 95번째 백분위수 세션 길이로, 세션의 95%가 이보다 짧음을 의미
- p99: 99번째 백분위수 세션 길이로, 세션의 99%가 이보다 짧음을 의미
이러한 각 지표는 요청에 얼마나 빠르고 안정적으로 응답하는지, 처리할 수 있는 트래픽 양, 전반적인 사용자 경험을 포함하여 로드 시 애플리케이션이 어떻게 수행되는지 테스트를 위한 중요한 정보들을 제공한다.
CI/CD 제공
Artillery는 CLI를 제공하고 Github actions, Jenkins, Circle CI, Gitlab CI/CD 등을 지원하여 CI/CD 파이프라인에서도 부하테스트를 해볼 수 있도록 한다. 이러한 도구들은 자동화가 중요한데 다양한 CI/CD 툴과 결합할 수 있으니 현업에서도 충분히 사용해볼만 한 것 같다.
정리
간단히 Artillery는 어떤 오픈소스인지 알아봤다. 기본적인 개념을 알아봤으니 다음편에서 실제 정상서버, 메모리가 낭비되고 있는 서버 두개를 구성하여 어떻게 부하테스트를 신뢰성 있게 테스트 해볼 수 있는지 정리해보려 한다.
참고자료
'Frontend' 카테고리의 다른 글
TDD로 배우는 웹 프론트엔드 강의 후기 (0) | 2024.04.28 |
---|---|
[Tanstack-Query] 핵심 로직 딥다이브 (0) | 2024.01.07 |
[TanStack Query] v5 주요 변경 사항 (0) | 2023.12.10 |
나는 웹 성능 지표를 잘 알고 있었나? (0) | 2023.06.04 |
그래서 모노레포가 뭐지? (feat. yarn workspace) (0) | 2023.04.09 |