k6를 사용한 부하테스트

석현·2024년 6월 15일
0

Insight

목록 보기
15/43
post-thumbnail

이런 경험 있으신가요?

운영 배포를 했는데 갑자기 메모리 누수가 발생해서 “심장이 멎는 줄 알았던” 경험이 있으신가요? 저요, 저! 마치 롤러코스터를 타는 기분이었죠. 배포 버튼을 누른 순간부터 모든 게 느려지더니, 서버는 거의 휘청거리고 있었습니다. 그래서 즉시 롤백을 해야 했습니다.

이런 상황을 피하려면 Release 단계에서 완벽하게 테스트하는 것이 중요하죠. “완벽한 테스트?” 아, 그거요. 저도 믿고 싶습니다. 특히 JVM을 너무 신뢰한 나머지 부하 테스트를 안 했던 것 같아요. “아니, JVM이 알아서 다 해주겠지!“라는 마음가짐이었죠. 모든 사항은 Release 단계에서 당연히 확인이 되었어야 했는데… 현실은 그렇지 않더군요.

JMeter, Gatling, Locust 등등 요즘 정말 많은 부하 테스트 도구들이 있지만, 오늘은 K6를 이용한 부하 테스트에 대해서 설명해보려고 합니다. 꼭 K6가 아니더라도 트래픽이 많거나 많아질 예정이라면! 부하테스트는 필수입니다!

K6란?

K6는 애플리케이션의 성능을 테스트할 수 있도록 도와주는 오픈 소스 부하 테스트 도구입니다. JavaScript로 작성된 테스트 스크립트를 통해 HTTP 엔드포인트에 대한 성능 테스트를 쉽게 수행할 수 있습니다. K6는 간단한 사용법과 강력한 기능을 제공하여 성능 테스트를 효율적으로 수행할 수 있게 해줍니다. K6를 부하테스트로 채택한 이유도 쉽고 빠르게 설정할 수 있었기 때문입니다.

K6 설치 방법

K6를 설치하는 방법은 여러 가지가 있습니다. 여기서는 Homebrew, Docker, 그리고 직접 바이너리 파일을 다운로드하여 설치하는 방법이있습니다. (k6 Official Installation)

Homebrew를 이용한 설치 (macOS)

brew install k6

Docker를 이용한 설치

docker pull grafana/k6

바이너리 파일을 이용한 설치 (Linux/Mac/Windows)

  • K6 릴리스 페이지로 이동하여 최신 버전을 다운로드합니다.
  • 다운로드한 파일을 압축 해제하고 실행 파일을 시스템의 PATH에 추가합니다.

언제 K6를 사용해야 할까?

너무나 당연한 이야기지만 K6뿐만 아니라 부하테스트를 왜 해야하는지에 대해서 이야기해보겠습니다.

애플리케이션의 성능 테스트

  • 애플리케이션이 예상되는 부하를 잘 처리할 수 있는지 확인하려면 K6를 사용하여 성능 테스트를 수행할 수 있습니다. K6는 여러 사용자가 동시에 시스템에 접근할 때 응답 시간이 어떻게 변화하는지 확인할 수 있습니다.

부하 분산 테스트

  • 다양한 시나리오에서 애플리케이션이 얼마나 많은 트래픽을 처리할 수 있는지 테스트할 수 있습니다. K6를 사용하면 특정 시간 동안 많은 사용자가 동시에 접속했을 때 시스템이 어떻게 반응하는지 확인할 수 있습니다.

CI/CD 파이프라인 통합

  • K6는 CI/CD 파이프라인에 통합하여 자동화된 성능 테스트를 수행할 수 있습니다. 배포 전에 성능 테스트를 자동으로 실행하여, 성능 문제가 있는지 확인할 수 있습니다. 이렇게 하면 배포 전 단계에서 잠재적인 문제를 미리 발견할 수 있습니다.

병목 현상 파악

  • 서버나 네트워크의 병목 현상을 찾아내고 해결책을 마련할 수 있습니다. K6를 사용하여 특정 요청의 처리 속도가 느려지는 부분을 식별하고, 이를 최적화할 수 있습니다. 성능 병목을 사전에 파악하면, 실제 운영 환경에서 발생할 수 있는 문제를 줄일 수 있습니다.

다양한 테스트 시나리오

  • K6는 다양한 테스트 시나리오를 작성하여 실행할 수 있습니다. 예를 들어, 특정 기능이 실행되는 동안 다른 기능이 동시에 잘 작동하는지 확인하거나, 특정 시간 동안 부하를 증가시키고 감소시키는 시나리오를 테스트할 수 있습니다.

실시간 모니터링

  • K6는 테스트 실행 중에 실시간으로 결과를 모니터링할 수 있습니다. 이를 통해 테스트 중 문제가 발생하면 즉시 대응할 수 있습니다. 실시간 모니터링을 통해 테스트 진행 상황을 파악하고, 예상치 못한 문제가 발생할 경우 신속하게 조치할 수 있습니다.

K6 어떻게 사용할까?

K6를 채택한 이유중 하나는 아주 아주 간단해서 입니다. 설치 하고 Script 만들고 실행시킨 후 잠시 기다리면 결과가 바로 나옵니다!

import http from 'k6/http';
import { check, sleep } from 'k6';

// 테스트 옵션 설정
export let options = {
    stages: [
        { duration: '30s', target: 20 }, // 30초 동안 가상 사용자를 20명까지 증가
        { duration: '1m', target: 20 },  // 1분 동안 가상 사용자 20명 유지
        { duration: '10s', target: 0 },  // 10초 동안 가상 사용자를 0명까지 감소
    ],
};

// 테스트 메인 함수
export default function () {
    // HTTP GET 요청을 보냄
    let res = http.get('http://localhost:8082/api/test');
    
    // 응답 상태가 200인지 체크
    check(res, {
        'status was 200': (r) => r.status == 200,
    });
    
    // 1초 대기
    sleep(1);
}

테스트 스크립트 실행

위의 스크립트를 작성한 후, 다음 명령어를 사용하여 K6 테스트를 실행합니다

k6 run test.js

Docker를 사용하는 경우, 다음 명령어를 사용합니다

docker run -i grafana/k6 run - <test.js

만약 오류가 난다면...!

위와 같이 오류가 출력되니 꼭! 확인해야합니다.

테스트가 실행되면 K6는 콘솔에 결과를 출력합니다. 결과에는 다음과 같은 정보가 포함됩니다:

http_reqs:

  • 전체 HTTP 요청 수를 나타냅니다.

vus:

  • 현재 활성화된 가상 사용자(Virtual Users) 수를 나타냅니다.

iteration_duration:

  • 각 테스트 반복(iteration)의 소요 시간을 나타냅니다.

http_req_duration:

  • 각 HTTP 요청의 소요 시간을 나타냅니다. 평균, 최소, 최대, 백분위수(p90, p95) 값을 포함하여 응답 시간을 상세히 분석할 수 있습니다.
  • 평균 응답 시간, 최소 응답 시간, 최대 응답 시간 등을 제공합니다.
  • 백분위수(p90)는 상위 90%의 요청이 특정 시간 이내에 완료되었음을 의미하고, p95는 상위 95%의 요청이 특정 시간 이내에 완료되었음을 의미합니다.

checks:

  • 성공/실패한 체크의 수를 나타냅니다.

data_received:

  • 테스트 중 수신한 데이터의 총량을 나타냅니다.

data_sent:

  • 테스트 중 전송한 데이터의 총량을 나타냅니다.

http_req_blocked:

  • HTTP 요청이 대기 상태에 있는 시간의 통계를 나타냅니다. 이는 요청이 네트워크 연결을 대기하거나 DNS 조회를 대기하는 시간 등을 포함합니다.
  • 평균 대기 시간, 최소 대기 시간, 최대 대기 시간 등을 제공합니다.

http_req_connecting:

  • HTTP 요청이 서버에 연결되는 시간의 통계를 나타냅니다. 이는 TCP 핸드셰이크에 소요되는 시간을 포함합니다.
  • 평균 연결 시간, 최대 연결 시간 등을 제공합니다.

http_req_tls_handshaking:

  • TLS 핸드셰이크 시간의 통계를 나타냅니다. 이는 HTTPS 요청 시 발생하는 TLS 설정에 소요되는 시간입니다.
  • 평균 TLS 핸드셰이크 시간, 최대 TLS 핸드셰이크 시간 등을 제공합니다.

http_req_waiting:

  • 서버에서 응답을 받기까지 대기한 시간의 통계를 나타냅니다. 이는 서버 처리 시간에 해당합니다.
  • 평균 대기 시간, 최소 대기 시간, 최대 대기 시간 등을 제공합니다.

iteration_duration:

  • 각 테스트 반복(iteration)의 전체 소요 시간을 나타냅니다.
  • 평균 반복 시간, 최소 반복 시간, 최대 반복 시간 등을 제공합니다.

vus_max:

  • 테스트 중 활성화된 최대 가상 사용자 수를 나타냅니다.

결론

부하 테스트는 마치 “운동 전 스트레칭”과도 같습니다. 아무리 준비가 잘 된 앱이라도, 부하 테스트 없이 갑자기 많은 사용자가 몰리면 마치 갑자기 풀코스를 달리는 것처럼 곧바로 쓰러질 수 있습니다. “에이, 설마 우리 서버가 버티지 못하겠어?“라고 생각할 수 있지만, 현실은 그렇지 않습니다.

상상해보세요. 당신의 앱이 드디어 세상의 빛을 보게 되어, 수많은 사용자가 한꺼번에 몰려듭니다. 서버는 “어? 뭐야 이게? 갑자기 이렇게 많이?“라며 혼란에 빠집니다. 그리고는… 다운! 그러면 사용자들은 “이 앱 뭐야, 왜 이래?“라며 떠나가겠죠. 이때 서버는 마치 바닷가에서 파도에 밀려 쓰러진 사람처럼 넋을 잃고 있습니다.

부하 테스트는 이런 상황을 예방하는 방패와도 같습니다. 미리 여러 시나리오를 통해 부하를 견디는 능력을 테스트해두면, 실제로 많은 사용자가 몰려와도 서버는 “이 정도쯤이야!” 하며 여유롭게 대응할 수 있습니다. 마치 마라톤 선수가 풀코스를 달리며 “아직도 기운이 넘친다!“고 외치는 것처럼요.

결론은, 부하 테스트를 통해 우리 앱을 강철 같은 몸으로 만들어야 합니다. “설마 이 정도 부하쯤이야!“라고 방심하지 말고, 꼼꼼하게 테스트하여 진정한 강자로 거듭납시다. 그러면 언제 어디서나, 어떤 부하가 몰려와도 끄떡없는 튼튼한 앱을 자랑할 수 있을 것입니다!

profile
Learner

0개의 댓글