본문 바로가기

Development/TIL

스트레스 테스트2 (feat. 배포 서버 다운)

오늘은 최종 프로젝트 브로슈어 제출일이었다.

브로슈어에 스트레스 테스트 지표를 추가하기 위해 무비위키의 배포된 서버에 테스트를 진행하던 중

과부하로 인해 서버가 다운이되었다.

비용을 투자하여 서버 성능을 업그레이드 시키느냐 로컬에 테스트를 진행하느냐 고민하다가

브로슈어 제출 시간이 얼마남지 않아 로컬에 빠르게 테스트를 진행하기로 했다.

배포된 서버는 aws의 프리티어를 이용한 것이라 성능이 로컬 서버와 큰 차이가 나지 않는다.

 

 

테스트 진행

artillery는 시나리오 테스트 진행을하면 결과를 json 파일로 저장을 하고 저장된 데이터를 바탕으로

테스트 결과를 visualizing 해준다. 그래서 단일 API 테스트였지만 시나리오 파일을 작성하여 진행했다.

먼저 root 디렉토리에 테스트를 진행할 시나리오를 작성할 json 파일을 만들었다.

더불어 테스트 결과가 저장될 파일도 만들어 준다.

 

테스트를 진행할 시나리오가 담긴 파일

테스트 결과가 저장될 파일

 

시나리오 파일 작성 예시

config에 테스트의 기본적인 조건 설정을 해준다.

scenarios의 flow에는 시나리오 흐름에 대해 설정해주었다.

유저의 행동을 모방하여 로그인과 검색같은 상황도 설정해줄 수 있다.

{
    "config": {
        "name": "첫번째 시나리오 테스트",
        "target": "http://localhost:3001",
        "phases": [
          {
             "duration": 60,
             "arrivalRate": 10
          }
       ]
    },
    "scenarios": [
       {
          "flow": [
             {
                "get": {
                   "url": "/post/94/record"
                }
             }
          ]
       }
    ]
 }

 

시나리오 테스트 json 파일을 위와 같이 작성한 후 아래와 같은 명령어를 입력하면 작성한 시나리오와 같이 테스트가 진행되고 myReport 파일에 결과가 자동으로 저장된다.

npx artillery run -o myReport scenariotest.json

 

myReport 파일에 저장된 테스트 결과 예시

데이터가 너무 많아 일부 생략했다.

{
  "aggregate": {
    "counters": {
      "vusers.created_by_name.0": 600,
      "vusers.created": 600,
      "http.requests": 600,
      "http.codes.200": 462,
      "http.responses": 462,
      "http.downloaded_bytes": 27927438,
      "vusers.failed": 138,
      "vusers.completed": 462,
      "errors.ETIMEDOUT": 138
    },
    "rates": {
      "http.request_rate": 5
    },
    "firstCounterAt": 1687749093228,
    "firstHistogramAt": 1687749100093,
    "lastCounterAt": 1687749161229,
    "lastHistogramAt": 1687749160073,
    "firstMetricAt": 1687749093228,
    "lastMetricAt": 1687749161229,
    "period": 1687749160000,
    "summaries": {
      "http.response_time": {
        "min": 203,
        "max": 9986,
        "count": 462,
        "p50": 391.6,
        "median": 391.6,
        "p75": 507.8,
        "p90": 804.5,
        "p95": 5598.4,
        "p99": 8868.4,
        "p999": 9801.2
      },
      "vusers.session_length": {
        "min": 208.7,
        "max": 9992.9,
        "count": 462,
        "p50": 399.5,
        "median": 399.5,
        "p75": 518.1,
        "p90": 820.7,
        "p95": 5598.4,
        "p99": 8868.4,
        "p999": 9801.2
      }
    },
=================================이하 생략=======================================

 

테스트가 완료되면 다음 명령어를 이용해 결과 데이터가 visualizing된 html 파일을 생성한다.

npx artillery report myReport

 

생성된 html 파일

 

html 파일을 실행시키면 데이터가 visualizing된 웹 페이지로 연결된다.

아래와 같이 테스트 결과들이 정리된 화면을 볼 수 있다.

 

 

이번 테스트에서 주목한 데이터

1. 응답 시간(Response Time): 응답 시간은 사용자가 요청을 보낸 후 시스템이 해당 요청에 대해 응답하는 데 걸리는 시간을 측정한다. 시나리오 테스트 결과에서는 http.response_time 지표를 활용하여 응답 시간의 분포와 통계 정보를 파악할 수 있다. 주로 median, p95, p99 데이터에 주목한다. median은 응답 시간의 중앙값, p95와 p99는 전체 응답 시간 중 가장 빠른 것부터 각각 95%, 99%를 의미한다. 이 수치들의 차이가 작을 수록 서버 성능이 안정적이라고 판단할 수 있다.

2. 처리량(Throughput): 처리량은 시스템이 단위 시간 동안 처리한 요청의 수를 나타낸다. 시나리오 테스트 결과에서는 http.requests 지표를 통해 전체 요청 수를 확인하고, http.request_rate 지표를 통해 초당 평균 요청 수를 살펴볼 수 있다.

3. 오류율(Error Rate): 오류율은 전체 요청 중에서 발생한 오류의 비율을 나타냅니다. 시나리오 테스트 결과에서는 vusers.failed 지표를 통해 실패한 가상 사용자 수를 확인할 수 있다. 이를 기반으로 전체 요청에 대한 오류율을 계산할 수 있다.

4. 가용성(Availability): 가용성은 시스템이 정상적으로 동작하는 시간의 비율을 나타냅니다. 시나리오 테스트 결과에서는 vusers.completed 지표를 통해 작업을 완료한 가상 사용자 수를 확인하고, 이를 전체 생성된 가상 사용자 수와 비교하여 가용성을 평가할 수 있다.

 

테스트 결과 summary

 

결론

테스트를 진행한 API들 중 특정 영화 게시글의 전체 버전 기록을 조회하는 API가 있었는데 다른 API들에 비해서 부하가 더 쉽게 걸렸다. 아무래도 로직이 더 복잡하고 저장된 게시글이 많을수록 출력해주는 데이터가 많아서 그런 것 같다.

 

곰곰히 생각해보니 게시글 전체의 버전 기록을 보여주는 방식은 굉장히 비효율적이다.

게시글 수정이 많이 될수록 데이터는 기하급수적으로 쌓일테고 매번 그 데이터들을 연산해서 보여주면 적은량의 요청으로도 서버에 과부하가 걸릴 수 밖에 없다.

 

따라서 게시글의 전체 버전 기록을 한번에 보여주는 것 보다는 버전ID 같은 것을 활용하여 각 버전을 네이밍해서 리스트를 띄워주고, 특정 버전ID를 상세 조회하면 직전 버전의 문서하고만 비교해주는 방식으로 성능개선을 하면 좋겠다는 생각이 들었다.

'Development > TIL' 카테고리의 다른 글

항해99를 마치며  (0) 2023.07.04
프로젝트 간단 소개 영상 제작  (0) 2023.06.28
스트레스 테스트 (feat. artillery)  (0) 2023.06.24
Redis Sorted Set (Zset)  (0) 2023.06.21
Nest.js 클러스터링  (0) 2023.06.21