프로그래밍/General

Artillery를 이용한 쉬운 부하 테스트(stress test)

Lou Park 2022. 7. 11. 19:04

Next.js로 앱을 처음 개발하고, 실제 서비스로 출시하기전 부하테스트를 해보려고 Artillery를 찾아보게되었는데, 너무 간단하고 쉬워서 공유를 해보려고 한다. 

 

# Install

npm을 이용해 컴퓨터에 artillery를 설치해준다.

딴얘기긴한데, 공식 홈페이지 너무 잘만들어 놓은거같다. 디자인이 완전 취향....

npm install -g artillery

artillery -v로 잘 깔렸는지 확인하면 된다. 공룡 보고싶으신 분들은 artillery dino라고 치시길

 

 

# Quick Start

quick은 하나의 HTTP endpoint를 테스트 할때 사용한다. 예로들자면 다음과 같다.

count는 50명의 가상유저들, num은 각각의 유저들이 100번의 GET 요청을 보낸다는 옵션이다.

atrillery quick --count 50 --num 100 http://localhost:3000
  • --output, -o <file>: 결과를 json으로 저장
  • --insecure, -k: 안전하지 않은 TLS 연결을 허용
  • --quiet, -q: 로그를 띄우지 않고 조용하게
  • --content-type, -t <content type>: Request의 content-type을 설정, 기본값은 application/json

 

 

# Test Script로 더 자세한 테스트하기

Artillery는 yaml 형식의 Test script를 지원하고있다. Test script는 크게 테스트 자체를 설정하는 config 부분과, 가상유저들의 행동, 테스트 케이스를 설정하는 scenarios 부분이있다. 아래는 그 설정파일의 예시다.

 

주석을 통해 어떤의미인지 적어두었는데, 공식문서를 통해 차근차근 보려면 여기를!

config:
  # 테스트 타겟. hostname, IP, URI가 될 수 있다.
  target: "http://localhost:3000"
  # timeout 시간은 7초
  http:
    timeout: 7
  # 가상유저를 생성하는 방법 
  phases:
      # 50명의 가상유저들을 5분동안 매 초 생성하되, 
      # 100명 이상의 동시 유저들은 없게 만드는 케이스.
      - duration: 300
        arrivalRate: 50
        maxVusers: 100
  # 사용할 변수들
  variables:
  	# 변수의 이름은 typeNumbers이고, 1~17까지의 숫자를 가졌음
    typeNumbers:
      - [1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,16,17]
      
scenarios:
  - flow:
  	# 루프를 돌면서 수행하려고함
    - loop:
      # GET http://localhost:3000/api/statistics?typeNumber=1
      - get: 
          url: "/api/statistics"
          # query parameter는 qs로 적어주어도되고, url에 바로 적어도된다.
          qs:
            typeNumber: "{{ $loopElement }}"
      # POST http://localhost:3000/api/statistics 
      # Body에는 json으로 { typeNumber: 1 } 이런식으로 들어가게 됨
      - post:
          url: "/api/statistics"
          json:
            typeNumber: "{{ $loopElement }}"
      # 변수 typeNumbers 요소들을 루프
      # 1, 2, ... 17이 차례로 $loopElement에 할당됨
      over: typeNumbers

Test script를 실행하기 위해서는 다음과 같이 명령어를 적어준다.

# Test script 이름이 config.yaml이고, 
# 결과물을 report_h.json으로 저장할 것이다.
artillery run config.yaml -o report_h.json

 

 

# Report 분석

로그에서는 이렇게 출력이 될 것이고, json 파일에서는 aggregate부분을 보면 똑같은 값들이 보일것이다. 

All VUs finished. Total time: 12 seconds

--------------------------------
Summary report @ 12:11:42(+0900)
--------------------------------

http.codes.200: ................................................................ 5000
http.request_rate: ............................................................. 298/sec
http.requests: ................................................................. 5000
http.response_time:
  min: ......................................................................... 14
  max: ......................................................................... 372
  median: ...................................................................... 159.2
  p95: ......................................................................... 223.7
  p99: ......................................................................... 347.3
http.responses: ................................................................ 5000
vusers.completed: .............................................................. 100
vusers.created: ................................................................ 100
vusers.created_by_name.0: ...................................................... 100
vusers.failed: ................................................................. 0
vusers.session_length:
  min: ......................................................................... 7663.6
  max: ......................................................................... 8288.3
  median: ...................................................................... 8186.6
  p95: ......................................................................... 8352
  p99: ......................................................................... 8352
  • http.requests: HTTP 요청 수
  • http.codes.200: 성공한 요청 수 (Status code = 200)
  • http.response_time: 응답 시간(ms)
  •  -min: 최소값
  •  -max: 최대값
  •  -median: 중위값
  •  -p95: 95% 분포값
  •  -p99: 99% 분포값