K6와 InfluxDB를 활용한 성능 테스트 및 모니터링 설계하기
by rowing0328Intro
이번 글에서는 K6를 활용한 성능 테스트를 다룬다.
성능 테스트의 개념을 간단히 정리한 뒤, K6를 이용해 테스트를 실행하고,
InfluxDB와 Grafana를 연동해 결과를 시각화하는 과정까지 기록할 예정이다.
성능 테스트란
성능 테스트(Performance Testing)는 소프트웨어, CPU, RAM 같은 자원의 성능을 측정하는 테스트다.
시스템이 특정 작업을 수행하는 데 걸리는 시간, 처리량, 사용 가능한 자원 등을 평가한다.
이 테스트를 통해 실제 트래픽 상황에서 시스템이 제대로 작동하는지와
서버가 다운되는 상황을 미리 확인할 수 있다.
얼마나 많은 트래픽을 감당할 수 있는지 파악하면,
운영 중 부하 발생 시 빠르게 대응해 서버 다운 같은 문제를 예방할 수 있다.
성능 테스트의 주요 카테고리
성능 테스트는 부하 테스트(Load Testing)와 스트레스 테스트(Stress Testing)로 나눌 수 있다.
부하 테스트 (Load Testing)
부하 테스트는 평소 트래픽과 최대 트래픽 상황에서 성능 변화를 확인하는 데 초점을 맞춘다.
애플리케이션 배포나 인프라 변경(예: 스케일 아웃, DB 장애 조치 등) 시 성능을 점검하며,
결제 처리 등 외부 요인으로 발생할 수 있는 예외 상황도 함께 점검한다.
스트레스 테스트 (Stress Testing)
스트레스 테스트는 서비스가 극한 상황에서 정상적으로 작동하는지 확인하는 테스트다.
장기간 부하가 지속될 때 시스템 한계와 최대 처리량을 측정하며,
테스트 이후 시스템이 자동으로 정상 복구되는지도 점검한다.
HomeBrew로 Mac OS에 K6 설치하기
Mac OS에서는 HomeBrew를 이용하면 K6를 간단하게 설치할 수 있다.
스크립트 작성
다음은 K6 성능 테스트에 사용할 GET API 예제 코드이다.
사용 예시 API
@Tag(
name = "Tech Info Blog",
description = "기술 정보 블로그 기본 및 상세 정보 조회 기능을 제공하는 API"
)
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("/tech-info/blog")
public class BlogController {
private final BlogReadService blogReadService;
@Operation(
summary = "블로그 기본 정보 조회",
description = "지정된 블로그 ID를 사용해 블로그 소개글과 소유자의 프로필 사진, 닉네임, 이메일을 반환합니다."
)
@ExceptionCodeAnnotations({CommonExceptionCode.NOT_FOUND_BLOG})
@GetMapping("{id}")
public BlogResponse getBlogBasicInfo(
@Parameter(description = "블로그 ID", example = "1") @PathVariable @NotNull Long id
) {
return BlogResponse.from(blogReadService.getById(id));
}
}
스크립트
import http from "k6/http";
import { sleep } from "k6";
export const options = {
vus: 1,
duration: "10s",
};
export default function () {
http.get("http://localhost:8080/api/tech-info/blog/1");
sleep(1);
}
설명
1. options 설정
- vus : 가상 사용자 수를 설정한다. 여기서는 1명으로 설정한다.
- duration : 테스트 시간을 설정한다. 10초 동안 요청을 보낸다.
2. http.get()
- GET 요청을 /api/tech-info/blog/1 경로로 보낸다.
3. sleep(1)
- 요청 후 1초 동안 대기한다.
- 이는 실제 서비스 환경처럼 요청 간 간격을 모방하기 위한 설정이다.
- 사용자가 한 번 요청하면 같은 요청을 1초 동안 반복하지 않는다는 가정에 기반한다.
실행 결과
기본 메트릭 (프로토콜에 관계없이 수집)
HTTP 요청 시 생성되는 메트릭
실제 테스트
앞서 진행한 테스트는 K6 사용법을 익히기 위한 간단한 예제였다.
하지만 성능 테스트는 실제 환경을 기반으로 세팅하고 진행하는 것이 중요하다.
이번에는 실제 환경을 구성하고, 구체적인 시나리오를 작성해 테스트를 진행해보려고 한다.
부하 테스트
아래는 기존 코드를 기준으로 수정된 K6 부하 테스트 스크립트다.
단계별 부하 증가와 성능 목표를 설정하여 테스트를 진행한다.
스크립트
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
stages: [
{ duration: '15s', target: 20 }, // 15초 동안 20명으로 증가
{ duration: '30s', target: 50 }, // 30초 동안 50명 유지
{ duration: '15s', target: 0 }, // 15초 동안 0명으로 감소
],
thresholds: {
http_req_duration: ['p(95)<400'], // 응답 시간 목표: 95%가 400ms 이내
http_req_failed: ['rate<0.01'], // 에러율 목표: 1% 미만
},
};
export default function () {
const res = http.get("http://localhost:8080/api/tech-info/blog/1");
sleep(1);
}
실행 결과
설명
1. 응답 시간
- 평균 : 11.52ms
- 95% 이내 : 19.57ms
- 목표 (500ms) 초과 달성
2. 에러율
- 실패율 : 0.00%
- 목표 (1% 미만) 달성
3. 요청 처리
- 총 910건의 요청 처리
- 최대 50명 가상 사용자 부하에서도 안정적
스트레스 테스트
서버의 한계치를 확인하고, 최대 부하 상황에서 성능이 어떻게 변화하는지를 평가하는 데 목적이 있다.
스크립트
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
stages: [
{ duration: '1m', target: 50 }, // 1분 동안 50명으로 점진적으로 증가
{ duration: '3m', target: 200 }, // 3분 동안 200명으로 부하 증가
{ duration: '2m', target: 500 }, // 2분 동안 500명의 피크 부하 유지
{ duration: '1m', target: 0 }, // 1분 동안 0명으로 부하 감소
],
thresholds: {
http_req_duration: ['p(95)<1000'], // 응답 시간 목표: 95%가 1000ms 이내
http_req_failed: ['rate<0.05'], // 에러율 목표: 5% 미만
},
};
export default function () {
http.get("http://localhost:8080/api/tech-info/blog/1");
check(response, {
"success": (res) => res.status === 200,
});
}
실행 결과
설명
1. 응답 시간 (http_req_duration)
- 평균 : 86.04ms
- 95% 이내 (p(95)) : 274.1ms
- 최대 : 1.52s
- 분석 : 응답 시간의 95%가 274.1ms 이내로 처리되어 안정적인 성능을 확인할 수 있었다.
2. 요청 실패율 (http_req_failed)
- 실패율 : 0.00%
- 분석: 모든 요청이 성공적으로 처리되었으며, 에러 없이 안정적으로 작동했다.
3. 데이터 처리량
- 수신 데이터 (data_received) : 634MB
- 송신 데이터 (data_sent) : 94MB
4. 요청 검증 (checks)
- 성공률 : 100%
- 모든 요청이 상태 코드 200으로 정상 처리되었다.
Docker Compose로 InfluxDB와 Grafana 환경 설정
InfluxDB와 Grafana를 컨테이너로 실행하기 위해 아래와 같은 docker-compose.yml 파일을 작성한다.
예제 코드
services:
influxdb:
image: influxdb:1.8
container_name: influxdb
ports:
- "8086:8086"
environment:
- INFLUXDB_HTTP_AUTH_ENABLED=false
- INFLUXDB_DB=k6
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- ./grafana/data:/var/lib/grafana
주의사항
InfluxDB 1.8은 내가 필요로 하는 간단하고 효율적인 데이터 저장과
시각화에 적합한 선택이었다.
이미 Grafana를 통해 시각화와 모니터링을 하고 있었기 때문에,
InfluxDB 2.x에서 제공하는 통합 대시보드나 고급 분석 기능은
필요하지 않았다.
InfluxQL은 SQL과 유사한 구조로,
단순한 데이터 조회와 시각화 요구를 충족하기에 충분했다.
복잡한 Flux 언어를 배울 필요 없이,
빠르고 직관적으로 데이터를 처리할 수 있다는 점에서 1.8이 더 적합했다.
또한, 1.8은 경량화된 구조로 내 환경에서
적은 자원으로도 안정적인 성능을 유지할 수 있었다.
결론적으로, 단순한 요구사항에 맞춘 간소한 운영이 가능했기 때문에,
1.8은 내가 원하는 목적에 완벽히 부합했다.
Grafana 대시보드 구성
데이터 소스 추가
Grafana 대시보드에서 InfluxDB를 데이터 소스로 추가한다.
1. Grafana에 로그인 (http://localhost:3000)
- 초기 아이디 & 비밀번호 : admin
2. DATA SOURCES 클릭
3. InfluxDB 선택 후 URL에 http://influxdb:8086 입력
4. Save & Test를 클릭해 설정을 저장하고 연결이 성공적으로 이루어졌는지 확인
대시보드 템플릿 활용
Grafana 공식 사이트에서 제공하는 템플릿을 활용하면 간단히 대시보드를 구성할 수 있다.
원하는 템플릿 ID를 검색한 뒤, Grafana의 Import 기능을 사용해 대시보드를 불러오면 된다.
이번 포스팅에서는 K6 Load Testing Results 템플릿을 사용한다.
1. DashBoard 클릭
2. New 클릭 후 Import 클릭
3. 아래 URL 접속 후 Copy ID to clipboard 클릭
k6 Load Testing Results | Grafana Labs
About A nice-lookin’ dashboard to visualize load testing results from the k6 load testing tool. Currently requires InfluxDB. See the k6 docs to set this up. Version History Version 1 - 06 July 2017 Version 2 - 18 July 2017 [Feature] Added drop-down for s
grafana.com
4. 복사된 ID를 입력 후 Load 클릭
5. Select a Prometheus data source 입력란을 클릭 후, 등록한 Prometheus Data Source를 선택한 뒤 Import를 클릭
6. K6 테스트 결과와 InfluxDB 연동
k6 run --out influxdb=http://localhost:8086/myk6db script.js
7. 아래와 같은 화면이 나타나면 설정이 성공적으로 완료
마무리
K6는 설치 과정이 간단하고,
독스가 잘 정리되어 있어 성능 테스트를 시작하기에 적합한 도구였다.
스크립트를 직접 작성해야 한다는 번거로움이 있지만,
이 과정에서 테스트에 대한 이해도와 숙련도를 높일 수 있었다.
특히, K6의 간결함과 유연함 덕분에
다양한 상황에서 성능 테스트를 빠르게 진행할 수 있다는 점이 인상적이었다.
앞으로 더 복잡한 시나리오에도 쉽게 적용할 수 있을 것 같아
활용도가 높다고 느꼈다.
참고 자료 :
Install k6 | Grafana k6 documentation
User-centered observability: load testing, real user monitoring, and synthetics Learn how to use load testing, synthetic monitoring, and real user monitoring (RUM) to understand end users' experience of your apps. Watch on demand.
grafana.com
Using k6 | Grafana k6 documentation
User-centered observability: load testing, real user monitoring, and synthetics Learn how to use load testing, synthetic monitoring, and real user monitoring (RUM) to understand end users' experience of your apps. Watch on demand.
grafana.com
'📌ETC > Development Log' 카테고리의 다른 글
Spring Boot와 LocalStack으로 AWS S3 테스트 환경 구성하기 (2) | 2025.01.20 |
---|---|
Spring Boot와 AWS S3 & CloudFront로 파일 관리 설계하기 (0) | 2025.01.16 |
Prometheus와 Grafana 활용한 Spring Boot 모니터링 설계하기 (1) | 2025.01.02 |
Spring Boot와 JSch 활용한 ElastiCache SSH 터널링 설계하기 (0) | 2024.12.17 |
Spring Boot 3.x JVM 통계, Grafana 대시보드로 분석하기 (5) | 2024.12.16 |
블로그의 정보
코드의 여백
rowing0328