Skip to content

Load Test (with K6)

Jaewon Lee edited this page Sep 9, 2024 · 7 revisions

K6 공식문서


Note

시스템의 성능을 평가하기 위해 시스템의 응답 시간, 처리량, 안정성 등을 측정하는 테스트


Load Test 수행 이유

항목 설명
성능 병목점 파악 시스템이 높은 트래픽에서 성능 저하를 일으키는 부분을 발견할 수 있다
안정성 확인 특정 부하 조건에서 시스템이 안정적으로 동작하는지 확인할 수 있다
용량 계획 시스템이 예상되는 사용자 수를 얼마나 잘 처리할 수 있는지 예측하여 필요한 리소스를 계획할 수 있다
성능 기준 검증 시스템이 설정된 성능 기준을 충족하는지 확인할 수 있다

Load Test의 주요 개념

항목 설명
Virtual Users (가상 사용자) 테스트 시 실제 사용자처럼 시스템에 접근하는 시뮬레이션된 사용자들
Transactions (트랜잭션) 사용자 작업을 정의하는 단위로, 하나의 트랜잭션은 하나 이상의 HTTP 요청을 포함할 수 있다
Throughput (처리량) 시스템이 일정 시간 동안 처리할 수 있는 요청의 수
Response Time (응답 시간) 요청을 보내고 응답을 받기까지 걸리는 시간
Concurrent Users (동시 사용자) 동시에 시스템에 접근하여 작업을 수행하는 사용자 수

Load Test 진행 시 확인해야 할 주요 사항

  1. 응답 시간(Response Time):
- 각 요청의 응답 시간
- 평균 응답 시간
- 최대 및 최소 응답 시간
  1. 처리량(Throughput):
- 초당 처리되는 요청 수
- 초당 전송되는 데이터 양
  1. 에러 비율(Error Rate):
- 요청 중 실패한 비율
- 에러 코드 및 원인 분석
  1. 자원 사용률(Resource Utilization):
- CPU 사용률
- 메모리 사용량
- 디스크 I/O
- 네트워크 대역폭 사용량
  1. 동시 사용자 수(Concurrent Users):
- 테스트 중 동시에 활동하는 사용자 수
- 사용자 증가에 따른 성능 변화
  1. 성능 병목 현상(Bottlenecks):
- 응답 시간이 급격히 증가하는 지점
- 자원 사용량이 급증하는 지점

주의사항

항목 설명
테스트 시나리오 정의 실제 사용 패턴을 반영한 시나리오를 작성하여 현실성 있는 테스트를 수행
데이터 준비 테스트에 필요한 데이터는 충분히 준비되어야 하며, 중복 데이터로 인한 오류를 방지
환경 일치 테스트 환경이 실제 운영 환경과 최대한 유사해야 정확한 결과를 얻을 수 있다
모니터링 테스트 동안 시스템의 자원 사용량을 지속적으로 모니터링하여 병목 현상을 파악
단계적 부하 증가 부하를 점진적으로 증가시켜 성능 한계를 파악

Load Test Types

chart-load-test-types-overview

항목 설명 VUs/처리량 기간 시기
Smoke Test 스크립트가 작동하는지, 시스템이 최소한의 부하에서 적절하게 작동하는지 검증 낮음 (2~20명) 짧음 (30초~3분) 관련 시스템 또는 애플리케이션 코드가 변경된 경우. 기능 로직, 기준 메트릭 및 편차를 확인
AverageLoad Test 예상되는 정상 조건에서 시스템의 성능을 평가 평균 중간 (5-60분) 시스템이 평균적인 사용으로 성능을 유지하는지 확인하기 위해 자주 확인
Stress Test 부하가 예상 평균을 초과할 때 시스템이 한계에서 어떻게 작동하는지 평가 높음 (평균 이상) 중간 (5-60분) 시스템 관리 방법을 확인하기 위해 평균 이상의 부하가 발생할 수 있는 경우
Soak Test 장기간에 걸쳐 시스템의 안정성과 성능을 평가 평균 길게 (오랜 시간) 장기간 연속 사용 시 시스템 점검을 위해 변경한 후
Spike Test 갑작스럽고 짧은 시간 동안 활동이 크게 증가하는 경우 시스템의 동작과 생존을 검증 매우 높음 짧음 (몇 분) 시스템이 시즌별 이벤트에 대비하거나 트래픽이 자주 폭주하는 경우
Breakpoint Test 시스템의 용량 한계를 파악하기 위해 점차적으로 부하를 증가 중단될 때까지 증가 필요한 기간 동안 시스템의 상한을 찾기 위해 몇 번이나

K6 사용 예시

1. K6 설치


2. script 작성

test.js

import http from "k6/http";

const BASE_URL = __ENV.BASE_URL || "http://localhost:3333";

export default function () {
  let restrictions = {
    maxCaloriesPerSlice: 500,
    mustBeVegetarian: false,
    excludedIngredients: ["pepperoni"],
    excludedTools: ["knife"],
    maxNumberOfToppings: 6,
    minNumberOfToppings: 2,
  };
  let res = http.post(`${BASE_URL}/api/pizza`, JSON.stringify(restrictions), {
    headers: {
      "Content-Type": "application/json",
      "X-User-ID": 23423,
    },
  });
  console.log(`${res.json().pizza.name} (${res.json().pizza.ingredients.length} ingredients)`);
}

3. script 실행

k6 run test.js

4. 결과 확인

          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: test.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

INFO[0000] The Big Pugliese (5 ingredients)              source=console

     data_received..................: 686 B 483 B/s
     data_sent......................: 323 B 227 B/s
     http_req_blocked...............: avg=1.22ms   min=1.22ms   med=1.22ms   max=1.22ms   p(90)=1.22ms   p(95)=1.22ms  
     http_req_connecting............: avg=223µs    min=223µs    med=223µs    max=223µs    p(90)=223µs    p(95)=223µs   
     http_req_duration..............: avg=417.43ms min=417.43ms med=417.43ms max=417.43ms p(90)=417.43ms p(95)=417.43ms
       { expected_response:true }...: avg=417.43ms min=417.43ms med=417.43ms max=417.43ms p(90)=417.43ms p(95)=417.43ms
     http_req_failed................: 0.00% ✓ 0        ✗ 1  
     http_req_receiving.............: avg=212µs    min=212µs    med=212µs    max=212µs    p(90)=212µs    p(95)=212µs   
     http_req_sending...............: avg=72µs     min=72µs     med=72µs     max=72µs     p(90)=72µs     p(95)=72µs    
     http_req_tls_handshaking.......: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=417.15ms min=417.15ms med=417.15ms max=417.15ms p(90)=417.15ms p(95)=417.15ms
     http_reqs......................: 1     0.703775/s
     iteration_duration.............: avg=1.42s    min=1.42s    med=1.42s    max=1.42s    p(90)=1.42s    p(95)=1.42s   
     iterations.....................: 1     0.703775/s
     vus............................: 1     min=1      max=1
     vus_max........................: 1     min=1      max=1


running (00m01.4s), 0/1 VUs, 1 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m01.4s/10m0s  1/1 iters, 1 per VU

5. 측정 항목 분석

항목 설명
http_reqs 요청 수(요청 비율)를 측정
http_req_failed 오류율(오류)을 측정
http_req_duration 응답 시간(대기 시간)을 측정
vus 가상 사용자 수(트래픽)를 측정

등의 지표를 확인할 수 있다.

더 자세한 사항은 메트릭 관련 문서에서 확인




SLI, SLO, SLA

관련 문서

Service Level Indicator (SLI, 서비스 수준 척도)

  • 프로젝트에 관련된 실제 정보 필요, 어떤 것을 테스트를 할지에 대한 구체적인 트러블 슈팅을 기록하는 것이 더 적합할 것 같음

Service Level Object (SLO, 서비스 수준 목표)

  • 프로젝트에 관련된 실제 정보 필요, SLI와 마찬가지

Service Level Agreements (SLA, 서비스 수준 협약)

  • 프로젝트에 관련된 실제 정보 필요 (크게 고려 사항은 아닐 것 같음)

Clone this wiki locally