포스트

(멋쟁이사자처럼_백엔드스쿨플러스) Day25~26 K6 성능테스트

K6 성능테스트

성능테스트

  • 성능테스트(Performance Test)는 시스템이나 소프트웨어의 성능을 측정하는 것을 말한다.
  • 웹 애플리케이션에서 사용하는 성능테스트에는 부하(Load), 스트레스(Stress) 테스트 등이 있다.

부하 테스트

  • 부하 테스트는 사용자가 정상적인 사용을 할 때의 성능을 측정하는 테스트이다.
  • 정상적인 조건과 최대 예상 사용자 수 조건에서 시스템의 응답시간, 처리량들을 특정한다.

일반적으로 예상되는 최대 사용자 수까지 점진적으로 사용자 수를 증가시킴
시스템의 성능 저하지점을 찾는것이 아닌, 정상 작동 상태에서의 성능을 확인

측정대상 : 응답시간, 처리량, 자원사용률

스트레스 테스트

  • 스트레스 테스트는 시스템의 한계를 찾기 위해 극한의 부하를 가하는 테스트이다.
  • 시스템이 극한 상황에서 어떻게 작동하고 실패하는 확인한다.

시스템이 처리할 수 있는 것 보다 더 많은 부하를 의도적으로 가함
시스템의 장애지점(Breaking Point)을 찾는것이 목적

측정대상 : 시스템의 안정성, 오류처리능력, 복구능력

K6 성능테스트

  • Grafana Labs에서 개발한 오픈 소스 부하 테스트 도구이다.
  • JavaScript로 테스트 스크립트를 작성할 수 있어 개발자 친화적이며, 성능 테스트를 위한 강력한 기능을 제공한다. Image

K6 설치

  • brew를 통해 설치할 수 있다.

    1
    2
    3
    
    brew install k6
      
     k6 --version
    

K6의 기본 구조

  • K6는 JavaScript로 테스트 스크립트를 작성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Counter, Rate, Trend } from 'k6/metrics';
import { htmlReport } from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js";

// 사용자 정의 메트릭 생성
const successfulLogins = new Counter('successful_logins');
const failedLogins = new Counter('failed_logins');
const errorRate = new Rate('error_rate');
const apiCallTrend = new Trend('api_call_duration');

// 테스트 옵션 설정
export const options = {
  // 단계별 부하 테스트 설정
  stages: [
    { duration: '1m', target: 20 },  // 1분 동안 20명까지 서서히 증가
    { duration: '2m', target: 20 },  // 2분 동안 20명 유지
    { duration: '1m', target: 50 },  // 1분 동안 50명까지 증가
  ],
  
  // 임계값 설정 (성능 SLO)
  thresholds: {
    http_req_duration: ['p(95)<200'], // 95% 요청이 200ms 이내 처리
    http_req_failed: ['rate<0.01'],   // 오류율 1% 미만
    'successful_logins': ['count>100'], // 최소 100번의 성공적인 로그인
    'api_call_duration': ['p(99)<300'], // 99% API 호출이 300ms 이내 처리
  },
};

// 기본 헤더 설정
const params = {
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
};

// 테스트 실행 함수
export default function () {
  // API 호출
  http.get('http://localhost:8090/api/v1/posts');
  // 현실적인 사용자 행동 시뮬레이션을 위한 일시 정지
  sleep(Math.random() * 3 + 1); // 1-4초 사이 랜덤 대기
}

// HTML 보고서 생성
export function handleSummary(data) {
  return {
    "result.html": htmlReport(data),
    "result.json": JSON.stringify(data),
  };
}
  • 실행은 다음 명령어를 입력한다.
1
2
3
4
k6 run script.js // 스크립트 실행
k6 run --out json=result.json test.js // JSON 결과 파일 생성
K6_WEB_DASHBOARD=true k6 run test2.js // 웹 대시보드 실행
K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_EXPORT=html-report.html k6 run script.js // HTML 보고서 생성

K6 메트릭

  • K6의 기본 메트릭의 주요 정의는 다음과 같다.

    METRIC NAMETYPE설명
    vusGauge현재 활성화된 가상 사용자 수
    vus_maxGauge가능한 최대 가상 사용자 수 (성능에 영향을 주지 않도록 VU 리소스는 미리 할당됨)
    iterationsCounter가상 사용자가 JS 스크립트 (기본 함수)를 실행한 총 횟수
    iteration_durationTrend한 번의 완전한 반복을 완료하는 데 걸리는 시간, 설정 및 해체에 소요되는 시간을 포함
    dropped_iterationsCounterVU 또는 시간 부족으로 시작되지 않은 반복 횟수
    data_receivedCounter수신된 데이터의 양
    data_sentCounter전송된 데이터의 양
    checksRate성공적인 체크의 비율
  • HTTP관련 메트릭은 다음과 같다.

    METRIC NAMETYPE설명
    http_reqsCounterk6가 생성한 총 HTTP 요청 수
    http_req_blockedTrend요청을 시작하기 전에 차단된(무료 TCP 연결 슬롯을 기다리는) 시간
    http_req_connectingTrend원격 호스트에 TCP 연결을 설정하는 데 걸린 시간
    http_req_tls_handshakingTrend원격 호스트와 TLS 세션을 핸드셰이킹하는 데 걸린 시간
    http_req_sendingTrend원격 호스트에 데이터를 전송하는 데 걸린 시간
    http_req_waitingTrend원격 호스트의 응답을 기다리는 데 걸린 시간
    http_req_receivingTrend원격 호스트로부터 응답 데이터를 받는 데 걸린 시간
    http_req_durationTrend요청에 걸린 총 시간 (http_req_sending + http_req_waiting + http_req_receiving)
    http_req_failedRatesetResponseCallback에 따른 실패한 요청의 비율

K6 웹 대시보드

  • 실시간 및 결과를 확인 할 수 있는 웹 대시보드를 제공한다. Image

  • 대시보드에 주요항목은 다음과 같다.

    항목내용비고
    VUs(Virtual Users가상유저수 
    Request Rate1초당 처리하는 요청수Throughput
    Request Duration요청에 대한 응답시간Latency
    Request Failed요청 실패 수 

    Throughput : 시스템이 처리하는 요청의 양

    • 초당 처리하는 요청수(트래픽, 트랜젝션)로 표현
    • ex) 1초에 1000개 처리 가능 => 쓰루풋이 1000TPS 이다

    Latency : 요청을 보낸 후 응답을 받기까지 걸린 시간

    • 응답시간, 지연시간, 대기시간 등으로 표현
    • 요청에 대한 평균 응답시간이 2.5초이면 => 평균 Latency 2.5초이다.

성능테스트 시각화

granfan, influxDB 설치

  • K6의 결과를 저장하고 시각화하기 위해 Grafana와 InfluxDB를 설치한다.
  • InfluxDB는 시계열 데이터를 저장하고, Grafana는 저장된 데이터를 시각화한다.

    version: '3.4'
      
    services:
      influxdb:
        image: influxdb:1.8
        ports:
          - "8086:8086"
        environment:
          - INFLUXDB_HTTP_AUTH_ENABLED=false
          - INFLUXDB_DB=k6
      
      grafana:
        image: grafana/grafana:latest
        ports:
          - "3000:3000"
        environment:
          - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
          - GF_AUTH_ANONYMOUS_ENABLED=true
          - GF_AUTH_BASIC_ENABLED=false
        volumes:
          - ./grafana:/etc/grafana/provisioning/
    

    grafana 접속 및 설정

  • localhost:3000으로 접속하여 로그인한다.
  • admin/admin으로 로그인한다.
  • Connections > Data sources > Add data source > InfluxDB 선택
  • URL : http://influxdb:8086, Database : k6로 설정한다.

    Image

Dashboard 생성

  • Dashboards > New dashboard > Import dashboard
  • https://grafana.com/grafana/dashboards/2587 > Load로 불러온다.

    Image

  • 테스트 실행

    1
    
    k6 run --out influxdb=http://localhost:8086/k6 script.js
    
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.