💎 들어가며

"포트폴리오에 유의미한 성과에 대해 적으려면 성능에 관해 적어야되는데 성능은 어떻게 체크할까?" 에 대해 고민하다가 Artillery를 알게 되었습니다.

이번 포스팅에서는 Artillery의 간단한 사용법에 대해 적어볼까 합니다.🤗


1.Artilley란?

Artilley는 Node.js 기반의 부하테스트 도구입니다. HTTP 혹은 websocket request를 원하는 시나리오대로 요청할 수 있습니다.

이를테면 아래 같은 상황을 재현할 수 있습니다.

"10분동안 초당 5개의 POST /api/info 와 같은 URL 요청을 쏜다."


2. 설치

우선 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에서 볼수 있습니다.


3. Test 들어가기

concept에 대해 정리하기 전에 Artillery란 무엇인지 파악하기 위해 우선 test 코드를 예제대로 짜서 따라해보았습니다.

3.1 quick 명령어

> 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 모드

3.2 run 명령어

Script 작성

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 명령어를 통해 작성한 스크립트를 수행합니다.

  • --output 옵션을 통해 JSON 형태의 리포트 파일을 받을 수 있습니다.

그 밖의 명령어에 대한 정보는 --help 옵션을 통해 얻을 수 있습니다.

> artillery run --help

Report

> 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 의 성능 지표를 표와 그래프로 보여줍니다.


3.3 Cloud Dashboard

저는 로컬 Report 보다 Cloud Dashboard 를 어떻게 이용하는 것일까가 더 궁금했는데요! (Cloud Dashboard의 통계가 더 이해하기 쉽게 느껴졌습니다)

아래 순서대로 진행하면 됩니다.


API Key 발급

  • https://app.artillery.io/ 에 접속합니다.
  • Dashboard에 로그인합니다.
  • Settings 메뉴 → API Keys 클릭한뒤, 새로운 API key를 만들어줍니다.

Run 시 key 추가

대시보드에 테스트 수행을 기록하려면 run 명령어 수행시 --record 옵션과 --key 옵션을 사용해야합니다.

아래는 --record 옵션과 --key 옵션을 사용한 예제입니다.

> artillery run my-service-test.yml --record --key 0x12345_my_api_key

결과 추적

대시보드의 메인화면에서 테스트 목록을 볼 수 있습니다.

하나의 테스트를 클릭하면 상세 결과를 볼 수 있습니다.


3.4 결과 분석

그래픽 보는 법

  • max: 가장 오래 걸린 요청 -> 응답 시간
  • p95: 전체 HTTP 트랜잭션 중 가장 빠른 것부터 95%까지 (대부분의 트래픽)
  • p50: 전체 HTTP 트랜잭션 중 가장 빠른 것부터 50%까지 (절반의 트래픽)
  • min: 가장 빠르게 온 요청 -> 응답 시간
  • p99: 이외에도 많이 사용하는데, 거의 모든 트래픽을 의미하기 때문

TPS 측정

TPS(Transaction Per Second)arrivalRate로 측정할 수 있습니다.

대부분의 경우 스트레스 테스트는 목표로 하는 TPS가 고정되어 있고 그 TPS를 맞춰야 하기 때문에 TPS를 고정 시킨 상태에서 코드나 인프라를 수정하면서 목표로 하는 TPS가 안정적인지 보면 됩니다.


4. Concepts

4.1 Scripts

Artillery의 테스트 스크립트는 YAML 파일로, 두가지 주요 section이 있습니다.

  • config: URI, Protocol 등 테스트를 위한 실행 환경 설정
  • senarios: 가상유저(VU, Virutal User)행동(behavior)을 정의

config

target

테스트할 엔드포인트(endpoint) 지정합니다.

config:
  target: 'http://localhost:8080'

phases

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 인증서를 수락하도록 지시할 수 있습니다. (보안이 중요하다면 권장하지는 않습니다.)


environments

하나의 테스트 스크립트에 다양한 환경을 정의할 수 있습니다.

예를 들어 로컬, 테스트서버, 프로덕션에서 동일한 성능 테스트를 실행하고자 할때, 각 환경에 대해 테스트 정의 파일을 복제하는 대신 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

scenarios 섹션에서는 Artillery가 생성할 가상 사용자(VU)에 대한 하나 이상의 시나리오에 대한 정의가 포함되어 있습니다.

각 시나리오는 애플리케이션 사용자가 보낸 일반적인 요청 또는 메시지 순서를 나타내는 일련의 단계입니다.


시나리오별 옵션

flow (필수)

가상 사용자가 수행하는 작업 배열입니다. HTTP 기반의 애플리케이션의 경우 GET 및 HTTP 요청을 실행하거나 Socket.io 테스트에 대한 이벤트를 내보낼 수 있습니다.

name (선택)

보고에 도움이 되는 설명이 포함된 이름을 시나리오에 할당합니다.

weight (선택)

새로운 VU가 시나리오를 선택할 확률을 다른 시나리오와 비교하여 가중치를 설정할 수 있습니다. 가중치가 높을 경우 높은 확률로 해당 시나리오가 선택됩니다.


before, after

시나리오가 시작되기 전에 사용할 수 있습니다.

다음 예시에서는 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 }}'

4.2 Commands

이 포스트에서는 기본적인 Command인 runquick에 대해서만 다룹니다

기본적인 Command

  • run - Artillery 테스트 스크립트를 실행합니다.
  • quick - 테스트 스크립트 없이 하나의 HTTP 엔드포인트를 테스트합니다.

AWS 관련 Command

  • run-lambda - AWS Lamda에서 분산 테스트를 수행합니다.
  • run-fargate - AWS Fargate에서 분산 테스트를 수행합니다.

💎 References


💎 마치며

Artillery를 사용해보면서 아직 추가 보완해야될 내용이 있지만, 생각보다 사용하기 쉽다고 느껴졌습니다!🤗

profile
Java, Spring 기반 풀스택 개발자의 개발 블로그입니다.

0개의 댓글