Artillery 부하 테스트 사용해보기

곽태민·2024년 1월 18일
0

TIL

목록 보기
63/65
post-custom-banner

개요

최근에 회사에서 갑작스러운 트래픽으로 서버가 다운됐었다😢 상황을 정리하자면 현재 회사는 Elastic Beanstalk(이하 EB)을 사용하고 있고, EB를 사용해서 ALB, EC2, Auto Scaling을 하고 있다.

그런데 여기서 Auto Scaling 하는 과정에서 CPU70% 이상이면 인스턴스를 복사해서 또 다른 인스턴스를 생성하게 되는데 기존 인스턴스가 너무 무거워지는 바람에 복사조차 못하고 그대로 서버가 가버렸다,,

여기서 생각했던게 너무 앞만 달려온 나머지 부하 테스트도 못하고 세상 밖으로 나오게 한 본인을 탓하며 지금이라도 부하 테스트를 적용하기 전 공부를 해보려고 한다.

현재 회사에서는 외부적 요인으로 인한 TDD를 못 하고 있지만, 이번 일로 unit teste2e test를 진행해보고 싶다. 원래 혼자 스터디 하면서 TDD를 하려고 노력했지만 실무에서는 해본 경험이 별로 없다,, (전회사에서는 unit test만,,)

그래도 이번에는 서버가 다운된 상황에서는 부하 테스트를 적극적으로 활용할 수 있을 것 같다.

부하 테스트란?

부하 테스트는 서버가 얼마나 많은 요청을 견딜 수 있는지 테스트를 하는 것이다. 일반적으로 development 환경에서는 많은 요청들이 오지도 않고,

서버에 동시 접속자 수일일 사용자 수를 확인할 수 없기 때문에 현재 서버가 견고한지 알 수 없다. 그래서 부하 테스트를 통해서 실제 서비스가 운영되는 서버 환경이랑 가장 환경이 비슷한 staging 환경에서 진행을 해볼 수 있을 것 같다.

What Is Artillery!

ArtilleryNode.js로 된 부하테스트 도구다. Artillery로 HTTP, Socket.IO, Websocket 등 많은 프로토콜을 지원한다. (gRPC, graphQL)

그리고, 시나리오 테스트를 통해서 부하테스트를 진행할 수 있다. 예를 들면 초당 1000명이 들어와서 한 API에 요청을 날린다던지 이런 시나리오를 통해서 더욱 더 현실감있는 부하 테스트를 할 수 있다.

해당 부하 테스트의 로그도 따로 지원을 해주고 있어서 원한다면 성능 지표계를 볼 수 있다.

설명한 것들 외에 여러 장점들이 있다. 이건 정말 안 쓸 수 없을 것 같다. 이제 Artillery에 대해서 소개를 했으니 한번 실습을 통해서 알아가 보려고 한다.

Artillery 사용법

우선 터미널에 아래와 같은 명령어를 통해서 Artillery를 설치한다.

npm i -g artillery artillery@latest

이렇게 설치하고 명령어를 통해서 버전 확인을 해보면

> yarn artillery version                           

        ___         __  _ ____
  _____/   |  _____/ /_(_) / /__  _______  __ ___
 /____/ /| | / ___/ __/ / / / _ \/ ___/ / / /____/
/____/ ___ |/ /  / /_/ / / /  __/ /  / /_/ /____/
    /_/  |_/_/   \__/_/_/_/\___/_/   \__  /
                                    /____/


VERSION INFO:

Artillery: 2.0.4
Node.js:   v18.17.0
OS:        darwin

이렇게 버전이 잘 뜨면 성공적으로 설치가 된 것이다.

> artillery quick --count 1000 -n 100 http://localhost:8080

이 명령어를 통해서 부하 테스트를 진행할 수 있는데, 일단 서버가 켜져 있어야 테스트가 가능한건 모두가 알 것이고, 각 명령어에 대해서 설명을 하자면
--count 옵션은 테스트할 사용자의 수를 의미하고,
-n 옵션은 요청 횟수를 의미하며
마지막으로 --rate 옵션은 초당 요청을 의미한다.

그래서 위에 부하 테스트를 실행 명령어를 해석해보면 1000명100번요청을 보내는 것이다. 어마어마한 요청 수 인것 같다!

아마 이걸 그대로 배포되어있는 서버에 부하 테스트를 진행한다면 아마 짐싸고 집에 갈 수 있을 거 같다.
(항상 AWS 과금 조심 및 서버 중단 조심)

일단 중요하게 봐야할 것을 정리를 하려고 한다.

여기서 보면 http.requests총 요청 수가 되면서 현재 10만번이라는 요청이 들어왔다. 실제 배포된 서버에 테스트할 생각에 벌써부터 손이 떨린다,,

그리고 http.responses는 아시다시피 총 응답 수가 되겠다. 지금 local에서 console.log를 이용해서 서버에 로그를 잘 찍히는 확인하는 정도라 그렇게 부하가 실리지는 않은 거 같다.

vusers.completedn번의 수행이 완료 vusers.created_by_name.0가상 이용자 수가 된다.

좀 더 보면 http.response_time이라고 보일 거다. 이 안에서 min제일 빠른 응답 시간, max제일 느린 응답 시간 median응답 시간 중간 값이 된다.

그리고 p95, p99는 100명 중 95번째(6번째)로 느린 응답 시간과 100명 중 99번째(2번째) 느린 응답 시간을 나타내는거다.

그래서 이 안에서는 median, p95, p99의 차이가 크지 않으면 성능이 좋은것으로 볼 수 있다.

Artillery 시나리오 테스트

Artillery를 통해서 시나리오 테스트도 가능하다. JSON 형식이나 YAML 형식으로 파일을 만들어서 시나리오 테스트를 진행할 수 있다.

본인은 API를 GraphQL로 간단하게 만들고, 시나리오 테스트 스크립트 YAML 형식의 load-test.yml로 만들 거다. (JSON으로 만들어도 무방)

config:
  target: 'https://localhost:8080'
  phases:
    - duration: 600
      arrivalRate: 50

scenarios:
  - name: 'loop load test'
    flow:
      - post:
          url: '/graphql'
          json:
            query: |
              query GetHelloQuery($input: GetHelloInput) {
                getHello(input: $input) {
                  messages
                }
              }
            variables:
              input:
                index: '3'
          capture:
            json: '$.data.getHello.messages'
            as: 'helloMessages'

본인은 반복문을 사용해서 index라는 field를 가지고 테스트를 할거다 index에 적힌 숫자대로 반복문을 돌 거고 내가 원하는대로 시나리오는 흘러갈 것이다.

해당 스크립트에 대해서 설명을 좀 하고 넘어가야할 필요가 있을 것 같다.

config sections

  • target: 테스트할 서버 url
  • phases: 테스트 요청 시간비율
    • duration, arrivalRate: 몇초 동안 매초 몇개의 요청을 보낸다.
      ex) duration: 60 arrivalRate: 30: 60초 동안 매초 30개의 요청을 보낸다.
  • defaults: 뒤에서 테스트할 시나리오의 기본값을 설정할 수 있다.
  • payload: 임의의 데이터를 보내기 위해서 사용.
    • 실제와 같이 요청 데이터를 다르게 테스트하고 싶으면 CSV 파일을 이용해서 진행 할 수 있다.
  • socketid: socket 테스트
    • query: socket들이 들어오는 주소 끝에 roomId로 query string을 달고 있어서 해당 query 부분을 작성해줘야 하는데, 방 생성 시 roomId가 달라지기 때문에 이 부분을 계속해서 바꿔줘야함.
  • plugins plugin 설정
  • ensure: 에러나 지연시간에 대해 성공 조건 설정
  • processor: 커스텀한 Javascript 코드를 불러온다.

Senarios Sections

  • name: 시나리오 이름
  • flow: 시나리오에서 진행하는 테스트 동작 순서
    • ex) QUERY, MUTATION 이런 요청 순서대로 보냄.
    • 각 요청에서 url로 호스트 명을 제외하고 path를 지정
  • capture: 응답으로 받은 데이터에서 다시 변수로 지정하여 뒤로 보내는 요청에 재사용.
  • match: 응답 데이터가 내가 원한 데이터 값으로 잘 오는지 확인.
  • weight: 시나리오에 대한 가중치다. 이 값이 높으면 해당 시나리오는 더 많이 발생.

이제 이런 설정이 완료됐다면 아래 명령어를 입력해서 테스트를 실행할 수 있다.

artillery run load-test.yml #파일명
profile
Node.js 백엔드 개발자입니다!
post-custom-banner

0개의 댓글