순간을 기록으로

[Artillery] 성능 테스트 도구로 배포한 애플리케이션 성능 측정 하기 본문

Development/Cloud

[Artillery] 성능 테스트 도구로 배포한 애플리케이션 성능 측정 하기

luminous13 2022. 5. 11. 00:22

안녕하세요. 이번 시간에는 저번에 포스팅했던 GCP에 올려놓은 cpu 바운드 애플리케이션의 성능을 측정해 보겠습니다. 성능을 측정하기 위해 스트레스 테스트 툴인 아틸러리(Artillery)를 사용하겠습니다. 아틸러리를 사용하기 위해서는 우선 nodejs를 설치해야 합니다.

1. NodeJS를 설치하기

혹시 nodejs가 설치되어 있을 수 있으므로 터미널에 node를 입력해봅니다. 만약 버전이 뜬다면 설치가 되어있는 상태입니다. 설치가 되어있지 않으면 구글에 nodejs를 입력하고 LTS버전의 인스톨러를 다운로드하여 설치합니다. 그리고 터미널에서 node -v를 입력하여 버전이 뜨면 설치가 정성적으로 된 상태입니다.

nodejs가 정상적으로 설치된 상태

2. 아틸러리 스크립트 폴더를 만들고 VSCode에서 열기

앞으로 작성할 아틸러리 스크립트를 저장할 아틸러리 스크립트 폴더를 생성합니다. 그리고 vscode에서 이 폴더를 열어줍니다.

3. 구글에 'node artillery'를 검색해서 공식 홈페이지에서 아틸러리 설치법과 사용법 배우기

위의 공식 사이트로 들어갑니다. 그리고 Document를 보면서 사용법을 익힐 수 있습니다.

Document에 들어간 화면입니다. 위 빨간 박스 안 명령어를 통해 아틸러리를 설치할 수 있습니다. 참고로 npm는 자바스크립트를 위한 패캐지 설치 도구입니다.

위 명령어를 복사한 뒤 vscode 터미널에서 위 명령어를 실행해 설치합니다.

4.첫 번째 테스트 스크립트 작성해보기

https://www.artillery.io/docs/guides/getting-started/writing-your-first-test#Load-Phases

[Writing Your First Test | Artillery

- What an Artillery test definition looks like

docs-nine-inky.vercel.app](https://www.artillery.io/docs/guides/getting-started/writing-your-first-test#Load-Phases)

아래 링크로 들어가 예제를 복사한 뒤 첫 번째 스크립트(cpu-test.yaml)에 붙여 넣습니다.

config:
  target: "https://example.com/api"
  phases:
    - duration: 60
      arrivalRate: 5
      name: Warm up
    - duration: 120
      arrivalRate: 5
      rampTo: 50
      name: Ramp up load
    - duration: 600
      arrivalRate: 50
      name: Sustained load
  payload:
    path: "keywords.csv"
    fields:
      - "keyword"

scenarios:
  - name: "Search and buy"
    flow:
      - post:
          url: "/search"
          json:
            kw: "{{ keyword }}"
          capture:
            - json: "$.results[0].id"
              as: "productId"
      - get:
          url: "/product/{{ productId }}/details"
      - think: 5
      - post:
          url: "/cart"
          json:
            productId: "{{ productId }}"

5.GCP VM인스턴스에 접속해서 CPU 바운드 애플리케이션 실행하기

  • sudo java -jar <파일명.jar>

vm인스턴스에 접속한 뒤 위 명령어를 입력하여 애플리케이션을 실행합니다.

6.cpu-test.ymal 스크립트 수정하기

VM 인스턴스 외부 IP 주소를 복사한 뒤 스크립트 안에서 다음과 같이 변경해줍니다.

  • target: "http://외부IP주소"

그리고 스크립트에서 필요하지 않은 부분은 제거하고 다음과 같이 작성하겠습니다.

접속할 제가 접속할 url은 get 메소드에 /hash/123입니다.

name에는 테스트 시나리오 이름을 지어줍니다.

위에 이미지를 보면 duration과 arrivalRate등 생소한 단어가 나옵니다. 도큐먼트를 살펴보면 위 코드는 60초 동안 성능을 측정하고 매초 1명의 새로운 가상 유저(vuser)를 생성한다는 뜻입니다. 즉 1분 동안 60개의 리퀘스트가 날아가게 됩니다.

  • duration: 테스트 시간
  • arrivalRate: 초당 생성할 가상 사용자 수

두 단어가 위의 의미임을 알 수 있습니다. 처음에는 잘 모르니깐 테스트 시간을 짧게 하고 가상 사용자도 적게 생성하겠습니다.

7. 스크립트 실행하기

  • MacOs
    • artillery run --output report.json 스크립트명.yaml
  • Windosw
    • artillery .cmd run --output report.json .\스크립트명.yaml

각 운영체제 별 실행 명령어입니다. vscode안 터미널에 명령어를 입력하면 테스트가 실행되고 테스트가 끝나면 현재 디렉토리에 report.json 파일이 생성됩니다.

이 report.json는 테스트 결과가 json 형식으로 들어있는 파일입니다.

이 파일을 보기 편하기 html 형식으로 만들기 위해서 다음 명령어를 입력합니다.

    • artillery report 스크립트명.json
  • 윈도우
    • artillery.cmd report .\스크립트명.json

이렇게 생성한 html 파일을 열면 다음과 같이 나옵니다.

report.html
저번 포스팅에서 측정한 속도와 비슷한 결과를 확일 할 수 있습니다.

위의 성능 결과표를 해석하면 다음과 같습니다.

  • 생성된 가상 유저 수 : 60
  • 완료된 가상 유저 수 : 44
  • 시나리오 횟수: 60번(100%)
  • 시간 초과 에러 16번
  • 요청(리퀘스트) 횟수: 60번
  • 200(성공) 횟수: 44번
  • 응답: 44번
  • 참고 latency는 지연시간을 의미한다.

결과 화면을 밑으로 내리면 그래프로 추가적인 정보를 확인할 수 있습니다.

duration과 arrivalRate 두 값을 조절하여 성능을 추가적으로 확인할 수 있습니다.

만약 내가 만든 API 성능을 측정하고 싶다면 목표 latency(지연시간)를 설정해야 합니다.

예를 들어 200~300ms의 레이턴시(지연시간)를 유지하겠다고 목표를 잡았다면, 결과 그래프를 확인하면서 300ms가 넘는 곳이 없어야 합니다. 이럴 경우 cpu가 더 많은 서버로 바꾸어 스케일업을 하거나 nginx를 앞에 세워서 로드밸런싱을 하여 스케일아웃을 해야 합니다.

마지막으로 더 좋은 cpu를 사용하여 스케일업을 하여 성능을 측정해 보겠습니다.

8. cpu가 더 좋은 서버로 바꾸어(스케일업) 성능 측정해보기

GCP에서 cpu를 더 좋은 것으로 바꾸어 보겠습니다. 아까와 똑같이 만들고 cpu만 다른 것으로 바꾸겠습니다.

(e2-micro/cpu2개 --> e2-highcpu-8/cpu8개)

이번에는 cpu가 8개인 인스턴스를 만들어 보겠습니다. 참고로 서울 리전에서는 제한이 있어 다른 리전에서 생성하겠습니다. 이전에 만든 인스턴스는 삭제 후 다시 만들겠습니다.

그리고 다시 설정을 하겠습니다.

  • sudo yum install wget
    • wget 설치하기
  • sudo yum install java
    • java 설치하기
  • wget <<jar파일 링크 주소>>
    • 깃허브에 저장한 jar 파일 다운로드하기
  • sudo java -jar 파일명.jar
    • jar 파일 실행하기
  • 스크립트에서 외부IP 변경하기
  • artillery run --output report.json 스크립트명.yaml
    • 맥 OS일 경우
  • artillery report 스크립트명.json

아래 이미지는 성능을 올린 후 성능 테스트 결과입니다.

  • 생성된 가상 유저:60명
  • 완료된 가상 유저:60명
  • 시나리오 횟수:60번(100%)
  • 에러 발생 x
  • 요청 횟수: 60번
  • 코드 200(성공) 횟수: 60번
  • 응답 횟수: 60번

이 전과 비교했을 때 결과가 큰 차이를 보이고 있습니다. 에러가 하나도 발생하지 않았습니다. 모든 테스트 케이스가 안정적인 모습을 보여주고 있습니다.

이전에는 응답 시간이 튀는 경우가 있었지만 이번에는 최대 응답 시간의 경우에도 안정적으로 772ms가 나오는 것을 확인할 수 있습니다.

그렇다면 실무에서는 어떤 기준을 잡고 성능테스트를 할까요?

방법은 크게 3가지입니다.

  1. 예상 TPS보다 여유롭게 성능 목표치를 잡는다.
    • 만약 예상 TPS가 1000이라면 트래픽이 튀는 것을 대비하여 3000~4000 정도의 TPS를 견딜 수 있는 인스턴스를 선택합니다
  2. API가 기대하는 Latency(지연시간)을 만족할 때까지 계속 성능 테스트를 해야 합니다.
    • 물론 스케일 아웃을 하여 지연시간을 만족할 수도 있겠지만, 가장 먼저 확인해야 되는 것은 단일 요청에 대한 Latency(지연시간)을 먼저 확인하는 것입니다. 만약 단일 요청에 대한 latency가 생각보다 높으면(=1.코드 효율성이 낮은 경우 , 2. 해당 API에서 I/O 병목현상이 일어나는 경우, 3.네트워크에서 지연시간이 발생하는 경우 등) 스케일 아웃을 해도 해결되지 않을 수 있습니다.
  3. 스케일 아웃을 해도 latency가 낮아지지 않으면 병목 현상을 의심하자.

번외로 그래프를 보면 응답시간 튀는 경우(위로 갑자기 솟는)가 있습니다. 이렇게 튀는 이유는 VM을 사용하기 있기 때문입니다. VM 인스턴스들은 인접한 인스턴스들과 자원을 공유하기 때문에 PM과 달리 테스트 결과가 항상 일정하지는 않습니다. 그렇기 때문에 이러한 것은 VM이기 때문에 어쩔 수 없는 결과라고 생각하면 됩니다.

오늘 배운 것을 다시 한번 정리해 보겠습니다.

  1. Artillery를 사용하기 위해서는 nodejs를 설치해야 한다.
  2. Artillery로 스크립트를 작성하여 애플리케이션 성능을 테스트하고 결과를 해석할 수 있다.
  3. 스케일 업을 하여 애플리케이션의 성능을 테스트하고 성능 향상을 인식할 수 있다.
Comments