최근에 팀에서 "우리 API가 실제로 얼마나 많은 트래픽을 처리할 수 있을까?"라는 궁금증이 생겨서 K6를 사용해 부하테스트를 진행해봤습니다. 생각보다 재미있는 경험이었어서 공유해보려고 해요.

가장 먼저 어떤 API들을 테스트할지 정했습니다. 실제 사용자들이 자주 사용하는 API들을 중심으로 선택했어요:
실제 사용 패턴과 비슷하게 이 API들을 랜덤하게 호출하는 방식으로 테스트를 설계했습니다.
여러 부하테스트 툴 중에서 K6를 선택한 이유는 다음과 같습니다:
macOS 환경에서는 Homebrew를 통해 간단하게 설치할 수 있습니다:
bash# K6 설치
brew install k6
vi api_load_test.js
k6 run --out json=results.json api_load_test.js
현실적인 상황을 고려해서 3가지 시나리오를 준비했습니다:
인증 없는 요청 🚫
토큰 없이 API를 호출해서 403 에러가 제대로 반환되는지 확인
잘못된 토큰 요청 ⚠️
유효하지 않은 토큰으로 요청해서 보안이 올바르게 작동하는지 테스트
정상적인 인증 요청 ✅
올바른 토큰으로 실제 사용자 시나리오를 모방한 테스트
갑작스러운 트래픽 폭증보다는 점진적인 증가가 현실적이라고 판단해서 다음과 같이 설계했어요:
1분: 초당 10개 요청 (워밍업) 🚶
2분: 초당 20개 요청
3분: 초당 50개 요청 🏃♀️
4분: 초당 60개 요청
5분: 초당 80개 요청
6~7분: 초당 100개 요청 (최대 부하) 🔥
javascript
export const options = {
scenarios: {
ramping_load: {
executor: 'ramping-arrival-rate',
startRate: 5,
timeUnit: '1s',
preAllocatedVUs: 50,
maxVUs: 300,
stages: [
{ duration: '1m', target: 10 },
{ duration: '1m', target: 20 },
// ... 점진적 증가
],
}
},
thresholds: {
http_req_duration: ['p(95)<2000'], // 95%의 요청이 2초 이내
http_req_failed: ['rate<0.01'], // 실패율 1% 미만
},
};
javascript
function saveLocation() {
const payload = JSON.stringify({
userId: Math.floor(Math.random() * 1000000),
latitude: (LAT_BASE + Math.random() * 0.1).toFixed(10),
longitude: (LON_BASE + Math.random() * 0.1).toFixed(10),
batteryLevel: randomIntBetween(10, 100).toString(),
});
const response = http.post(`${BASE_URL}/api/locations`, payload, {
headers: AUTH_HEADERS
});
return check(response, {
'Location save success': (r) => r.status === 200,
});
}
부하가 높아질수록 로그 출력을 줄여서 성능에 미치는 영향을 최소화했습니다:
javascript
function shouldLog() {
const currentRate = __ENV.CURRENT_RATE || 0;
if (currentRate <= 10) {
return __ITER % 10 === 0; // 낮은 부하: 자주 로그
} else if (currentRate <= 50) {
return __ITER % 50 === 0; // 중간 부하: 적당히
} else {
return __ITER % 100 === 0; // 높은 부하: 가끔만
}
}
테스트 완료 후 다음과 같은 메트릭을 확인할 수 있었습니다:
점진적 부하 증가의 중요성
갑작스러운 부하보다는 천천히 증가시키는 것이 실제 상황과 유사하고, 시스템의 한계점을 정확히 파악할 수 있었습니다.
로그 관리의 필요성
높은 부하 상황에서는 로그 출력 자체도 성능에 영향을 줄 수 있다는 걸 깨달았어요.
다양한 시나리오 테스트의 가치
단일 API보다는 실제 사용 패턴을 모방한 혼합 시나리오가 더 의미 있는 결과를 제공했습니다.
K6를 사용한 부하테스트는 생각보다 간단하면서도 강력한 도구였습니다. 서비스의 성능 한계를 미리 파악하고 대비할 수 있어서 매우 유용했어요.
아직 부하테스트를 도입하지 않으신 팀이 있다면 K6로 시작해보시는 걸 추천드립니다. 설치도 간단하고 학습 곡선도 완만해서 금방 익숙해지실 수 있을 거예요! 🙌
혹시 K6 사용하면서 궁금한 점이나 더 나은 방법이 있으시면 댓글로 공유해주세요!