Stress Test

프로젝트 막바지에 들어서자 멘토님으로부터 만든 서비스에 대해 테스트를 한 번 진행해 보라는 조언을 들었습니다.

류석영 교수님의 강의 영상을 보면서 처음으로 테스트와 테스트 주도 개발에 대해 알게 된 이후로 항상 제가 짠 코드를 테스트 하는 것에 대해 관심을 가지고 있었고, 종종 이러한 관심을 내비쳤던지라 제가 테스트를 진행해보게 되었습니다.

테스트 기초지식 조사

NPM Trend를 통해 어떤 테스트를 많이 하는가 비교해보니 단위 테스트용 라이브러리인 jest가 압도적으로 인기 있었고, E2E 테스트용 라이브러리인 Cypress도 jest에 비할바는 아니지만 성능 테스트용 라이브러리인 Artillery에 비하면 훨씬 많이 쓰이더군요.

프로젝트 마무리 단계에서는 E2E테스트를 많이 하는 것 같았습니다만, 무언가 결과를 보여줄 만한 테스트를 하려니 소프트웨어 테스트보다는 성능 테스트가 더 상황에 맞을 것 같아, 결국 제가 동경해왔던 테스트와는 별로 상관이 없는 종류의 테스트를 진행하게 되었습니다. (그래도 이 쪽 테스트도 재미있었습니다.😄)

Artillery가 WebRTC와 socket.io에 대한 테스트도 지원해서 처음에는 다른 팀원들이 담당한 WebRTC를 이용한 영상 통화 기능을 테스트 해보려고 했는데, 영상 통화 품질을 어떻게 테스트 해야 하나 막막해서 일단은 API에 대한 테스트를 먼저 준비했습니다. (결국 WebRTC는 프로젝트 최종발표 전까지 어떻게 테스트하면 좋을지 생각해내지 못했습니다 😢)

테스트 진행

테스트는 Artillery라는 라이브러리를 이용해 진행하였습니다.

config:
  target: "테스트 API 주소"
  payload:
    path: "users.csv"
    fields:
      - "userId"
      - "subjectId"
    cast: false
  phases:
  - duration: 100
    arrivalRate: 1 
    rampTo: 10000
    name: "RAMP test"
    
    #서버가 감당할 수 있는 한계를 측정하기 위해 
    #초당 1명의 유저부터 시작해서 
    #마지막에는 초당 10000명의 유저가 접속하는 시나리오입니다.
    
scenarios:
  - name: "Kaburi"
    weight: 1
    flow:
    
      - post:
          url: "/studytime"
          form:
            userInfo: "{{ userId }}"
            subjectId: "{{ subjectId }}"
            startTime: "{{2022-02-10 00:50:13}}"
          capture:
            - json: $.id
              as: "studyId"
        #각각의 가상의 유저는 새로운 공부기록을 저장하고
      - think: 1
      	#1초 기다린 뒤에
      - patch:
          url: "/studytime/{{ studyId }}"
          form:
            userInfo: "{{ userId }}"
            endTime: "2022-02-10 00:50:14"
        #공부기록을 갱신합니다

테스트 시나리오 수행

Http용 테스트 시나리오는 yaml으로 작성했습니다. 작성하는 방식은 공식문서에 잘 적혀있고, 같은 라이브러리를 사용해서 테스트를 진행해본 분들이 올려놓은 예시가 많아 조금씩 따라해보면서 쓰면 되서 시간이 걸리긴 했지만 아주 어렵지는 않았습니다.


위의 시나리오를 수행해서 얻은 기록을 artillery가 기본으로 제공하는 기능을 통해 차트로 만들었습니다. 녹색 선이 가상의 사용자가 보낸 요청의 수고 분홍색 선이 사용자가 받은 status 200 응답이고, 검은색 선은 timeout error입니다.

10회 가량 테스트 한 결과 평균적으로 초당 요청이 230번 정도 들어오기 시작하면 응답이 사라지기 시작하는 것이 확인되어 어떤 부분에서 병목이 일어나는지 확인해보기 위해 다음 테스트를 준비 했습니다.

병목구간 확인

API가 원체 단순하다보니 사용자로부터 요청을 받고 RDS에서 자료를 받아 응답을 보낼때까지 시간을 로그로 남겨 확인해 보기로 하였습니다.

결과 초당 200회 요청이 발생하면 응답시간에 지연이 발생하기 시작하는 것을 확인 하였고, 결과적으로 사용자가 발생시키는 초당 요청이 200회 이상 발생하는 구간이 오기 전에 스케일 업 해야한다는 결론에 도달하게 되었습니다.

테스트를 마치고

처음 생각보다 테스트를 하면 할 수록 결과와 함께 '왜 이런 결과가 나오지?'라는 생각이 들 때가 많아 이래저래 조건을 바꾸어가며 테스트를 하다보니 시간도 생각보다 훨씬 오래 걸렸고, 원래 관심을 가지고 있었던 소프트웨어 테스트와는 전혀 다른 테스트였지만, 하나씩 원인을 찾아나가는 과정이 생각보다 재미있었습니다.

또한 테스트의 결과에 대해 확실한 원인을 찾기 위해서는 사용 중인 언어와 컴퓨터 아키텍쳐에 대한 이해가 더욱 필요하겠구나 하는 생각이 들어 CS 기반지식에 대한 중요성을 다시 느끼는 계기가 되었습니다.

좋은 웹페이지 즐겨찾기