💬 왜 성능 테스트가 필요할까?
PostDM 프로젝트는 사용자들이 견적서를 생성하고 조회할 수 있는 플랫폼입니다. 이번 프로젝트에서는 Spring Boot와 MySQL 데이터베이스를 활용했으며, 사용자 수 증가나 데이터 증가에 따라 서버가 얼마나 안정적으로 버틸 수 있을지 고민해야 했습니다.
실제 서비스가 운영될 때 다음과 같은 문제가 발생할 수 있습니다. 이런 문제를 사전에 예측하고 대응하기 위해 성능 테스트를 진행했습니다.
- 특정 시간대에 트래픽이 몰려 API 응답이 느려짐
- 동시 요청 처리량(Throughput)이 낮아 사용자가 대기하거나 실패
- DB에 부하가 집중되어 전체 성능 저하
- 예기치 못한 에러로 인한 장애 발생
이번 글에서는 성능 테스트를 위한 도구는 어떤 게 있는지 정리하고, 이 중 JMeter로 프로젝트 성능 테스트 과정과 결과를 공유하고자 합니다.
성능 테스트 도구 종류
| 도구 이름 | 특징 |
| Apache JMeter | - Java 기반의 오픈소스 성능 테스트 도구 - GUI 기반으로 직관적 - 리소스 사용량이 많음 (GUI 실행 시 무거움, 대규모 테스트엔 CLI 권장) - 복잡한 테스트 시나리오 구성 가능 |
| Locust | - Python 기반의 성능 테스트 도구 - 시나리오를 코드로 작성 - 이벤트 기반 방식으로 많은 유저를 동시에 시뮬레이션 가능 - 리소스 소비가 적음 - 복잡한 시각화 기능은 부족 (Grafana, Prometheus 연동 필요) |
| k6 | - JavaScript로 테스트 스크립트를 작성하는 CLI 기반 도구 - DevOps 및 클라우드 환경과의 연동을 고려해 설계됨 - 코드 작성 방식으로 버전 관리와 자동화에 유리 - CLI 중심으로 CI/CD와 통합이 쉬움 - Grafana, Prometheus 등 APM 도구와 쉽게 연동 가능 - 경량, 빠른 실행 |
| Gatling | - Scala 기반의 DSL로 성능 테스트를 구성 - 코드 기반 시나리오 설계에 적합 - 성능이 뛰어남 (동시 요청 처리 능력이 좋음) - 코드 기반이므로 재사용성과 테스트 유지보수가 좋음 - CI/CD 연동에 강함 - HTML 리포트로 세부적 |
| Artillery | - Node.js 기반의 경량 성능 테스트 도구 - JSON/YAML 기반 설정으로 테스트 시나리오 작성이 쉬움 - Node.js 환경과 잘 통합되어 JS 기반 백엔드 프로젝트에 적합 - 설치 및 사용이 간단하고 기능이 단순함 |
왜 JMeter를 선택했는가?
PostDM 프로젝트에서는 다음과 같은 이유로 Apache JMeter를 선택했습니다.
- GUI 제공: 성능 테스트 입문자로서 GUI 환경에서 요청 흐름을 시각적으로 이해할 수 있었습니다.
- HTTP 요청 테스트에 최적화: REST API 테스트를 손쉽게 구성할 수 있어 Spring Boot 서버의 주요 API 성능을 빠르게 검증할 수 있었습니다.
- 병렬 요청, 스레드 수 조정 기능: 동시에 수백 건의 요청을 보낼 수 있어 동시성 처리 검증에 유리했습니다.
- 결과 리포트 제공: 테스트 결과를 테이블 형태로 시각화해 분석하기 좋았습니다.
프로젝트에서 JMeter 사용해 보기
1. 테스트 대상 API 선정
트래픽이 집중될 가능성이 높은 견적서 API를 우선 선정했습니다.
- 견적서 상세 조회 API (GET /api/v1/estimates/{id})
- 견적서 전체 조회 API (GET /api /v1/estimates)
2. 테스트 시나리오 구성

- 데이터 조건: 10,000건의 더미 견적서를 미리 추가
- HTTP Request: JWT 토큰을 포함한 인증 요청 구성
- Summary Report, Aggregate Report, View Results Tree: 응답 시간, 에러율, TPS 확인
- Thread Group: 사용자 수 100명, Ramp-up 시간 1초, Loop Count 10, 각 테스트당 1000회

3. 테스트 결과
[Docs] 견적서 전체 및 상세 조회 API 성능 테스트 리포트 · Issue #67 · fullstack-dev-hub/postdm
📌 테스트 개요 항목 내용 목적 견적서 API 성능 측정 및 개선 사항 파악 대상 API GET /api/v1/estimates (전체 조회)GET /api/v1/estimates/{id} (상세 조회) 데이터 조건 약 10,000건의 견적서 요청 수 각 테스트
github.com


- 견적서 전체 조회 응답 크기 평균이 약 1.5MB로 평균 응답 데이터 크기가 과도하게 큼
- 견적서 상세 조회 반복 요청 시에도 성능이 개선되는 현상이 나타남 ( Cold Start → Warm State)
문제 분석 및 해결 방안 도출
문제 분석
- 견적서 전체 조회 API에 페이징을 적용하지 않아 평균 응답 데이터 크기가 과도하게 큼
- 동일한 요청에 대해 DB를 반복 조회하는 구조
- 캐시 미사용으로 모든 요청이 DB까지 도달
해결 방안
- 페이지네이션 도입
- 견적서 전체 조회 API에 페이징 적용
- Redis 캐시 도입
- 견적서 상세 조회 API에 대해 캐시 적용
- @Cacheable을 활용해 자주 조회되는 데이터를 Redis에 저장
- 쿼리 최적화
- 불필요한 LEFT JOIN 제거
- 인덱스 추가 및 N+1 문제 해결
- 부하 분산 고려
- 로드밸런서, DB 리플리케이션 등을 고려
💬 마무리하며
이번 JMeter 성능 테스트는 단순히 수치를 확인하는 데 그치지 않고, 실제 시스템 병목 구간을 찾아내고 개선하는 데 큰 도움이 되었습니다. 백엔드 개발자로서 성능과 안정성을 고려한 설계를 할 수 있는 역량을 키울 수 있었던 경험이었습니다.
이번 성능 테스트 결과를 바탕으로 페이지네이션과 Redis 캐싱을 도입해 보았습니다. 다음 글에서 이를 어떻게 적용했으며, 성능 테스트 결과가 얼마나 향상되었는지 정리해 보겠습니다.
이후에는 남은 해결 방안인 쿼리 최적화와 부하 분산을 고려하고자 합니다. 더 나아가서 성능 테스트 결과를 CI/CD 파이프라인에 넣는 자동화도 추가해 보면 좋을 것 같습니다.
'프로젝트' 카테고리의 다른 글
| Redis란 무엇인가?: Spring Boot에 캐시로 적용해보기 (1) | 2025.07.10 |
|---|---|
| 페이지네이션: 성능 최적화를 위한 첫걸음 (0) | 2025.06.23 |
| Access Token 재발급: Refresh Token의 역할 (0) | 2025.05.13 |
| JWT 기반 인증: 로그아웃은 어떻게 구현할까? (0) | 2025.04.17 |
| 팀 디스코드 봇 만들기(feat. Docker 활용) (1) | 2025.01.15 |