"포트폴리오에 유의미한 성과에 대해 적으려면 성능에 관해 적어야되는데 성능은 어떻게 체크할까?" 에 대해 고민하다가 Artillery를 알게 되었습니다.
이번 포스팅에서는 Artillery의 간단한 사용법에 대해 적어볼까 합니다.🤗
Artilley는 Node.js 기반의 부하테스트 도구입니다. HTTP 혹은 websocket request를 원하는 시나리오대로 요청할 수 있습니다.
이를테면 아래 같은 상황을 재현할 수 있습니다.
"10분동안 초당 5개의 POST /api/info 와 같은 URL 요청을 쏜다."
우선 Artillery는 Node 기반의 프로그램이기 때문에 Node가 설치되어있어야합니다. 터미널에 아래와 같은 명령어를 통해서 Artillery를 설치해줍니다.
npm install -g artillery@latest
이렇게 설치하고 아래 명령어를 통해서 버전이 잘 확인되면 잘 설치된 것입니다.
> npx artillery version
___ __ _ ____
_____/ | _____/ /_(_) / /__ _______ __ ___
/____/ /| | / ___/ __/ / / / _ \/ ___/ / / /____/
/____/ ___ |/ / / /_/ / / / __/ / / /_/ /____/
/_/ |_/_/ \__/_/_/_/\___/_/ \__ /
/____/
VERSION INFO:
Artillery: 2.0.15
Node.js: v20.10.0
OS: win32
자세한 내용은 공식 Docs에서 볼수 있습니다.
concept에 대해 정리하기 전에 Artillery란 무엇인지 파악하기 위해 우선 test 코드를 예제대로 짜서 따라해보았습니다.
> artillery quick --count 1000 -n 100 http://localhost:8080
artillery를 빠르게 실행해보는 방법은 quick 명령어를 사용하는 것입니다. 테스트 스크립트 없이 API를 테스트 해볼 수 있습니다.
artillery quick [TARGET] [-c <value>] [-n <value>] [-o <value>] [-k] [-q]
주요 옵션
-c
, --count value
: 생성할 가상 사용자 수 (기본 값: 10)-n
, --num
: 가상사용자가 보샐 요청 수 (기본 값: 10)-o
, --output
: JSON 리포트 파일명-q
, --quiet
: Quiet 모드config:
target: "http://localhost:8080"
phases:
- duration: 60 # 지속시간
arrivalRate: 5 # 초당 요청수
scenarios:
- name: Books
flow:
- post:
url: "/api/books"
60초 동안 초당 5명의 사용자가 동시접속을 시나리오로 도서목록 요청을 보내는 간단한 테스트 스크립트 입니다.
> artillery run test.yml --output test.json
run 명령어를 통해 작성한 스크립트를 수행합니다.
그 밖의 명령어에 대한 정보는 --help 옵션을 통해 얻을 수 있습니다.
> artillery run --help
> artillery report test.json
report 명령을 날리면 DEPRECATION 경고와 함께 html을 생성해줍니다.
> artillery report test.json
┌───────────────────────────────────────────────────────────────────────┐
│ DEPRECATION NOTICE │
├───────────────────────────────────────────────────────────────────────┤
│ The "report" command is deprecated and will be removed in a future │
│ release of Artillery. │
│ │
│ Artillery Cloud is now the recommended way to visualize test results. │
│ It provides more comprehensive reporting, advanced visualizations, │
│ and includes a free tier. │
│ │
│ Sign up on https://app.artillery.io │
└───────────────────────────────────────────────────────────────────────┘
Report generated: test.json.html
test.json.html
을 클릭해서 들어가보면 test.json 의 성능 지표를 표와 그래프로 보여줍니다.
저는 로컬 Report 보다 Cloud Dashboard 를 어떻게 이용하는 것일까가 더 궁금했는데요! (Cloud Dashboard의 통계가 더 이해하기 쉽게 느껴졌습니다)
아래 순서대로 진행하면 됩니다.
대시보드에 테스트 수행을 기록하려면 run 명령어 수행시 --record 옵션과 --key 옵션을 사용해야합니다.
아래는 --record 옵션과 --key 옵션을 사용한 예제입니다.
> artillery run my-service-test.yml --record --key 0x12345_my_api_key
대시보드의 메인화면에서 테스트 목록을 볼 수 있습니다.
하나의 테스트를 클릭하면 상세 결과를 볼 수 있습니다.
TPS(Transaction Per Second)는 arrivalRate로 측정할 수 있습니다.
대부분의 경우 스트레스 테스트는 목표로 하는 TPS가 고정되어 있고 그 TPS를 맞춰야 하기 때문에 TPS를 고정 시킨 상태에서 코드나 인프라를 수정하면서 목표로 하는 TPS가 안정적인지 보면 됩니다.
Artillery의 테스트 스크립트는 YAML 파일로, 두가지 주요 section이 있습니다.
테스트할 엔드포인트(endpoint) 지정합니다.
config:
target: 'http://localhost:8080'
phases는 Artillery가 구체적으로 가상 유저(VU, 이하 VU)를 어떻게 생성할 지에 대해 정의합니다.
phases는 리스트로 여러가지 단계(phase)가 포함 될 수 있습니다.
phases:
- name: ramp up
duration: 30m
arrivalRate: 1
rampTo: 100
- name: pause
duration: 1h
- name: sustain
duration: 3h
arrivalRate: 100
name 옵션
CLI 로그 및 Artillery Cloud 대시보드에서 더 쉽게 식별할 수 있도록 단계에 이름을 지정할 수 있습니다.
> artillery run artillery.yml
# 이름 지정시
Phase completed: test (index: 0, duration: 10s) 12:05:34(+0900)
# 이름 미지정시
Phase started: unnamed (index: 0, duration: 10s) 12:05:51(+0900)
duration 옵션
초(s)단위의 단계 시간 (VU가 생성되는 도착 시간)을 의미합니다.
arrivalRate 옵션
초당 생성할 VU를 정의합니다. 아래 예시에서는 5분(300초) 동안 매초 50명의 VU를 생성합니다.
phases:
- duration: 300
arrivalRate: 50
arrivalCount 옵션
한 단계에 VU를 지정할 수 있습니다. 아래 예시에서는 60초 안에 20명의 가상 사용자를 만듭니다. (대략 3초마다 한 명의 가상 사용자)
phases:
- duration: 60
arrivalCount: 20
maxUsers 옵션
최대 VU를 지정할 수 있습니다. 아래 예시에서는 5분 동안 매초 10명의 VU를 생성하며, 특정 시간에 최대 50명의 동시 VU를 생성합니다.
phases:
- duration: 300
arrivalRate: 10
maxVusers: 50
rampTo 옵션
duration 동안 VU를 rampTo 옵션 만큼 늘립니다. 아래 예시에서는 2분 동안 가상 사용자의 도착률을 10명에서 50명으로 늘립니다.
phases:
- duration: 120
arrivalRate: 10
rampTo: 50
pause 옵션
아무것도 하지 않는 단계를 구성할 수 있습니다.
config:
target: 'https://staging.example.com'
phases:
- pause: 60
tls 옵션
Artillery로 https 연결을 하게 되면 자체 서명된 인증서에 한해 아래와 같은 에러가 발생할 수 있습니다.
⇒ errors.UNABLE_TO_VERIFY_LEAF_SIGNATURE
Postman으로 해당 URL을 날려보면 아래와 같은 에러를 볼 수 있죠
⇒ SSL Error: Unable to verify the first certificate
config:
tls:
rejectUnauthorized: false
이 때 TLS 옵션으로 Artillery가 자체 서명된 TLS 인증서를 수락하도록 지시할 수 있습니다. (보안이 중요하다면 권장하지는 않습니다.)
하나의 테스트 스크립트에 다양한 환경을 정의할 수 있습니다.
예를 들어 로컬, 테스트서버, 프로덕션에서 동일한 성능 테스트를 실행하고자 할때, 각 환경에 대해 테스트 정의 파일을 복제하는 대신 config.environments
설정을 통해 환경 별로 구성을 정의할 수 있습니다.
config:
target: 'http://service1.acme.corp:3003'
phases:
- duration: 10
arrivalRate: 1
environments:
production:
target: 'http://service1.prod.acme.corp:44321'
phases:
- duration: 1200
arrivalRate: 10
local:
target: 'http://127.0.0.1:3003'
phases:
- duration: 1200
arrivalRate: 20
테스트를 실행할 때 -e
옵션을 사용하여 명령줄에서 환경을 지정할 수 있습니다.
> artillery run my-script.yml
> artillery run -e local my-script.yml
특정 환경에서 테스트를 실행할 때 $environment
변수를 사용하여 현재 환경의 이름에 액세스할 수 있습니다.
scenarios:
- flow:
- log: 'Current environment is set to: {{ $environment }}'
scenarios 섹션에서는 Artillery가 생성할 가상 사용자(VU)에 대한 하나 이상의 시나리오에 대한 정의가 포함되어 있습니다.
각 시나리오는 애플리케이션 사용자가 보낸 일반적인 요청 또는 메시지 순서를 나타내는 일련의 단계입니다.
flow (필수)
가상 사용자가 수행하는 작업 배열입니다. HTTP 기반의 애플리케이션의 경우 GET 및 HTTP 요청을 실행하거나 Socket.io 테스트에 대한 이벤트를 내보낼 수 있습니다.
name (선택)
보고에 도움이 되는 설명이 포함된 이름을 시나리오에 할당합니다.
weight (선택)
새로운 VU가 시나리오를 선택할 확률을 다른 시나리오와 비교하여 가중치를 설정할 수 있습니다. 가중치가 높을 경우 높은 확률로 해당 시나리오가 선택됩니다.
시나리오가 시작되기 전에 사용할 수 있습니다.
다음 예시에서는 before 섹션에서 인증 요청을 호출하고 가상 사용자가 도착하기 전에 인증 토큰을 캡처합니다. 시나리오가 실행된 후 after섹션에서는 토큰을 무효화합니다.
config:
target: 'http://app01.local.dev'
phases:
- duration: 300
arrivalRate: 25
before:
flow:
- log: 'Get auth token'
- post:
url: '/auth'
json:
username: 'myUsername'
password: 'myPassword'
capture:
- json: $.id_token
as: token
scenarios:
- flow:
- get:
url: '/data'
headers:
authorization: 'Bearer {{ token }}'
after:
flow:
- log: 'Invalidate token'
- post:
url: '/logout'
json:
token: '{{ token }}'
이 포스트에서는 기본적인 Command인 run과 quick에 대해서만 다룹니다
기본적인 Command
run
- Artillery 테스트 스크립트를 실행합니다.quick
- 테스트 스크립트 없이 하나의 HTTP 엔드포인트를 테스트합니다.AWS 관련 Command
run-lambda
- AWS Lamda에서 분산 테스트를 수행합니다.run-fargate
- AWS Fargate에서 분산 테스트를 수행합니다.Artillery를 사용해보면서 아직 추가 보완해야될 내용이 있지만, 생각보다 사용하기 쉽다고 느껴졌습니다!🤗