안정적이고 확장 가능한 서비스를 운영하기 위해서는 기능 구현뿐 아니라 성능 및 부하 테스트가 필수적입니다.
특히 API가 동시에 많은 요청을 받을 때 잘 버텨주는지 확인하지 않으면, 실제 운영 환경에서 큰 장애로 이어질 수 있죠.
대표적인 오픈소스 부하 테스트 도구로는 Apache JMeter와 nGrinder가 있으며, 본 글에서는 상대적으로 단순하고 접근성이 높은 JMeter를 먼저 살펴보고 간단한 실습을 진행하겠습니다. 🔍

JMeter란?
Apache JMeter는 아파치 소프트웨어 재단에서 개발한 오픈소스 부하·성능 테스트 툴입니다.
웹 애플리케이션뿐 아니라 다양한 네트워크 서비스의 응답 성능, 처리량, 안정성을 점검할 수 있도록 설계되어 있어요.
원래는 웹 애플리케이션 테스트용으로 시작했지만, 지금은 훨씬 더 범용적으로 진화했습니다.
HTTP/HTTPS 요청은 물론이고, JDBC, FTP, LDAP, SOAP, JMS, SMTP/POP3/IMAP 메일 프로토콜까지 지원하기 때문에
“웹 서버 성능 측정 도구”를 넘어 “범용 성능 테스트 프레임워크”라고 할 수 있습니다.
주요 특징
1) 100% Java 기반
- JMeter는 Java로 구현되어 있어 운영체제에 구애받지 않고 JVM만 있으면 실행 가능합니다.
- Windows, macOS, Linux 모두 지원되며, 설치도 단순히 압축을 풀고 실행 스크립트를 돌리면 됩니다.
- Java 기반이라 멀티플랫폼 호환성이 뛰어나고, 라이브러리 확장성도 높습니다.
2) GUI 환경 제공
- jmeter.sh 또는 jmeter.bat을 실행하면 Swing 기반의 GUI가 뜹니다.
- 시나리오 구성을 드래그 앤 드롭으로 할 수 있어 비개발자도 직관적으로 학습 가능합니다.
- 예: “Thread Group” → “HTTP Request” → “Listener(결과보기)”를 추가하는 것만으로도 간단히 테스트 가능.
- GUI뿐만 아니라 CLI(커맨드라인) 모드도 지원하여, CI/CD 파이프라인이나 서버 환경에서도 자동화 가능.
3) 스레드 기반 가상 사용자 (Virtual User)
- JMeter의 부하 발생 원리는 스레드(Thread)를 이용한 가상 사용자 시뮬레이션이에요.
- Thread Group 설정에서 가상 사용자의 수(스레드 수), Ramp-up 시간(얼마나 점진적으로 늘릴지), Loop 횟수(몇 번 반복할지)를 지정할 수 있습니다.
- 이를 통해 “100명이 동시에 로그인하면 서버가 어떻게 버틸까?” 같은 시나리오를 손쉽게 구현할 수 있습니다.
4) 플러그인 에코시스템
- JMeter는 풍부한 플러그인 생태계를 갖추고 있어, 기본 기능 이상으로 확장 가능합니다.
- 예시:
- 다양한 리포트/그래프 뷰어 (Response Times Over Time, Throughput Shaping Timer 등)
- 고급 제어기(Controller), 추가 샘플러(Sampler), 모니터링 플러그인
- 덕분에 단순히 TPS/응답시간만 보는 게 아니라, 부하 패턴 제어, 응답 본문 검증, 실시간 시각화까지 가능해집니다.
5) 다양한 프로토콜 지원
- 가장 많이 쓰이는 건 HTTP/HTTPS 기반 API 테스트지만,
- DB 연결(JDBC), 메시징(JMS), 메일(SMTP/POP3/IMAP), FTP 업로드/다운로드, LDAP 인증 등도 지원합니다.
- 즉, 엔드투엔드(End-to-End) 시나리오를 하나의 툴에서 구성할 수 있습니다.
한마디로 JMeter는 쉽게 시작할 수 있는 GUI 도구이면서 멀티프로토콜 지원 & 플러그인 확장성으로 범용 성능 테스트 플랫폼으로 자리 잡은 툴이에요.
JMeter 설치 & 실행
요구 사항
- Java Development Kit(JDK): 최소 JDK 8 이상, 권장 JDK 11 이상
→ JMeter는 100% Java 기반이라 JDK 필수. java -version으로 버전 확인 가능 - 운영체제: Windows, macOS, Linux 모두 지원 (JVM만 있으면 OK)
다운로드
- 공식 사이트 접속 👉 https://jmeter.apache.org/download_jmeter.cgi

- 최신 버전의 Binary zip (압축 파일) 다운로드 ( 저는 apache-jmeter-5.6.3.zip로 다운로드하였습니다! )
- 원하는 위치에 압축을 해제합니다.
~/tools/apache-jmeter-5.6.3/
실행 방법
GUI 모드 실행로 실행해보겠습니다.
cd ~/tools/apache-jmeter-5.6.3/bin
./jmeter.sh

위와 같은 명령어를 실행하면 Swing 기반 GUI가 열리면서 Test Plan 화면이 나타납니다.

서버 환경이나 CI/CD 파이프라인에서 자동화할 때는 CLI 모드를 사용할 수도 있습니다.
./jmeter.sh -n -t test-plan.jmx -l result.jtl -e -o ./report
- -n: Non-GUI 모드 실행
- -t: 실행할 테스트 플랜 파일 (.jmx)
- -l: 결과 저장 파일 (.jtl)
- -e: 테스트 종료 후 HTML 리포트 생성
- -o: 리포트 출력 디렉토리
실행 완료 후 ./report/index.html을 열면 브라우저에서 결과 대시보드 확인 가능!
부하 테스트 시나리오 만들기
이제 실제 API를 대상으로 부하를 걸어보는 테스트를 만들어볼 차례입니다!_!
Thread Group(스레드 그룹) 추가
부하를 발생시킬 “가상 사용자”를 정의하는 단계입니다.
- 좌측 트리에서 Test Plan → Add → Threads (Users) → Thread Group 클릭
- 아래와 같이 주요 옵션을 설정합니다.
| 옵션 | 설명 | 예시 |
| Number of Threads (users) | 동시에 접속할 가상 사용자 수 | 50 |
| Ramp-up period (seconds) | 사용자를 몇 초에 걸쳐 늘릴지 | 10 |
| Loop Count | 각 사용자가 요청을 반복할 횟수 | 5 |


👉 예: 50명의 사용자가 10초 동안 점진적으로 늘어나면서 총 5번씩 요청 → 총 250회 요청 발생
HTTP Request(요청) 샘플러 추가
테스트할 API를 지정하는 단계예요.
- Thread Group → Add → Sampler → HTTP Request
- 아래처럼 설정합니다.
| 옵션 | 설명 | 예시 |
| Server Name or IP | 테스트 대상 도메인 | sy-develop-note.tistory.com |
| Path | API 경로 | /get |
| Method | 요청 방식 | GET |
(저는 로컬에서 실행 중인 Spring Boot API를 대상으로 테스트를 진행했기 때문에 `Server Name`에 `localhost`, `Port Number`에는 애플리케이션이 실행 중인 포트인 `8080`을 입력했습니다. 🙂)


Listener(리스너) 추가 – 결과 확인용
테스트 결과를 눈으로 확인하려면 리스너를 추가해야 합니다.
- Thread Group → Add → Listener
- 추천 리스너:
- ✅ View Results Tree – 요청/응답 상세 로그 확인
- 📊 Summary Report – 평균 응답 시간, TPS, 에러율 확인
- 📈 View Results in Graph – 실시간 성능 그래프


실행 및 결과 해석
이제 상단의 ▶ 버튼을 눌러 테스트를 실행해 봅시다.
테스트가 끝나면 Summary Report에서 다음과 같은 지표를 확인할 수 있습니다.
| 항목 | 설명 |
| Samples | 총 요청 수 |
| Average | 평균 응답 시간(ms) |
| Throughput | 초당 처리 요청 수 (TPS) |
| Error % | 실패율 |

테스트를 실행한 결과, 아래와 같은 성능 지표를 확인할 수 있었습니다.
✅ 테스트 설정
- 50 Threads × 5 Loop → 총 250개의 요청 수행
✅ 결과 요약
| 항목 | 값 | 해석 |
| Samples | 250 | 총 250회의 요청이 실행되었음을 의미합니다. (50명의 가상 사용자가 각각 5번 요청) |
| Average (평균 응답 시간) | 2 ms | 서버가 요청에 응답하는 데 걸린 평균 시간이 약 2ms로 매우 빠릅니다. 즉, 요청을 거의 즉시 처리하고 있다는 뜻이에요. |
| Min / Max (최소·최대 응답 시간) | 1 ms / 18 ms | 가장 빠른 응답은 1ms, 가장 느린 응답도 18ms 수준으로 전체적으로 안정적입니다. 큰 편차 없이 일관된 속도를 유지하고 있어요. |
| Std. Dev (표준편차) | 1.97 | 응답 시간 변동폭이 작다는 뜻으로, 성능이 일정하게 유지되고 있습니다. |
| Error % (오류율) | 0.00% | 250건 요청 모두 성공했으며 실패한 요청이 없습니다. 서버가 모든 요청을 정상적으로 처리했다는 뜻이에요. |
| Throughput (TPS) | 25.4/sec | 초당 약 25.4건의 요청을 처리했습니다. 이 수치는 서버의 기본 처리 능력을 보여주며, 현재 설정에서 서버가 초당 약 25건의 요청을 안정적으로 소화 가능하다는 뜻이에요. |
| Received KB/sec / Sent KB/sec | 20.61 / 3.10 | 초당 약 20.61KB를 수신하고 3.10KB를 전송하고 있다는 뜻으로, 네트워크 사용량이 크지 않은 테스트 시나리오임을 알 수 있습니다. |
| Avg. Bytes (평균 바이트 수) | 830 | 응답 본문의 평균 크기가 약 830바이트라는 뜻이에요. |
TPS(Throughput Per Second)는 서버가 초당 처리할 수 있는 요청 수를 의미합니다. 이 수치를 기준으로 서버의 최대 처리량(capacity)을 가늠할 수 있으며, 실제 운영 환경에서 예상되는 트래픽과 비교하여 여유가 있는지 판단하는 지표로 활용할 수 있습니다.
✏️ 마무리
이렇게 JMeter를 활용하면 별다른 설정 없이도 간단하게 API 부하 테스트를 진행할 수 있습니다.
특히 GUI 환경에서 몇 가지 옵션만 지정하면 가상의 사용자를 만들어 실제 트래픽 상황을 손쉽게 시뮬레이션할 수 있다는 점이 큰 장점이에요.
“성능 테스트”라고 하면 어렵고 복잡할 것 같지만, JMeter는 입문자도 금방 익힐 수 있을 만큼 직관적이라 빠르게 성능 테스트를 시작해 보기 좋은 툴이라고 느꼈습니다.
다만 JMeter는 단일 머신에서 실행된다는 특성상 대규모 트래픽 테스트나 분산 환경 테스트에는 한계가 있어요.
실제 운영 환경과 가까운 조건에서 테스트하려면 더 강력한 도구가 필요하죠.
그래서 다음 글에서는 분산 부하 테스트에 특화된 오픈소스 툴인 “nGrinder”를 활용해 더 발전된 부하 테스트를 진행하는 방법을 다뤄보려 합니다. 👩🏻💻
'개발끄적' 카테고리의 다른 글
| nGrinder로 시작하는 부하 테스트 가이드 (0) | 2025.10.20 |
|---|---|
| MSA 환경에서 살아남기 위한 멀티모듈 구조 (0) | 2025.03.22 |
| 413 Request Entity Too Large 오류 해결하기 (Nginx & Node.js 환경) (0) | 2025.03.05 |
| 414 Request-URI Too Large 오류 해결 방법 (0) | 2024.11.21 |
| GraphQL vs REST: 어떤 것을 선택할 것인가? (0) | 2024.11.18 |