카테고리 없음

JMeter를 활용한 성능 테스트

엽승 2025. 5. 10. 16:11
728x90

이미지를 업로드하는 API를 개발한 뒤, 실제로 얼마나 빠르게 동작하는지 궁금했습니다.
사용자 입장에서는 업로드가 빠르게 끝나는 것이 중요하기 때문에, 성능 테스트 도구인 JMeter를 활용하여 직접 부하 테스트를 해봤습니다. -> https://jmeter.apache.org/download_jmeter.cgi

 

Apache JMeter - Download Apache JMeter

Download Apache JMeter We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be ava

jmeter.apache.org

 

 

2. 테스트 준비

✅ 테스트 대상 API

  • Method: GET
  • Endpoint: /products/18
  • 기능: 특정 상품 조회  ->  1

✅ 테스트 환경

  • 로컬 Spring Boot 서버 (Mac)

 

다운로드 후 진행 

1. 압축해제 tar -xvzf apache-jmeter-5.6.3.tgz

2. cd apache-jmeter-5.6.3/bin

3. ./jmeter

 

 

다운로드 후 Jmeter 실행 

Test Paln -> add-> sampler -> HttpRequest 만들기 GET 요청에 부하 테스트 

 

 

✅ 1. Number of Threads (스레드 수 = 가상의 사용자 수) 즉

: 동시에 몇 명의 사용자가 요청을 보낼지 설정
예) 10으로 설정하면, 10명의 사용자가 동시에 API를 호출하는 것처럼 테스트함 
📌 실제 사용자가 몰릴 상황을 시뮬레이션할 때 사용함 (ex. 이벤트 시작, 로그인 몰림) -> 

 

 

✅ 2. Ramp-Up Period (램프업 시간, 초 단위)

: 모든 사용자를 몇 초에 걸쳐 순차적으로 투입할지 정함
예) 스레드 수가 10이고 Ramp-Up이 5초면, 0.5초마다 한 명씩 요청을 보냄

📌 서버에 한꺼번에 부담을 주지 않고 점진적으로 부하를 가할 때 사용
📌 Ramp-Up = 0이면, 모든 요청이 동시에 시작됨 → 실제 트래픽 폭주 상황 시뮬레이션 가능

계산법 : Ramp-Up Period (초) = Thread 수 / 초당 투입하고 싶은 사용자 수

즉 쓰레드가 20이고 사용자수가 1이면  Ramp-Up = 20 

 

✅ 3. Loop Count (루프 횟수)

: 한 명의 가상 사용자가 몇 번 요청을 반복할지
예) 5로 설정하면, 각 스레드가 요청을 5번 반복해서 보냄 → 총 요청 수 = 스레드 수 × 루프 수

📌 API 반복 호출 성능 측정, 캐싱 테스트, DB 부담 테스트 등에 사용됨

 

Threads Ramp-Up Loop Count 의미

10 0 1 10명이 동시에 1번 요청 (폭주 시뮬레이션)
10 10 1 1초마다 1명씩 10명 요청
5 5 5 5명이 1초마다 요청 시작, 각자 5번씩 요청 (총 25회)

 

 

 

MAC 기준 CMD + R  단축키를 이용해 실행한다. 

 

 

 

요약하자면 

✅ 전체 요약

  • 요청 성공 (HTTP 200)
  • 총 응답 시간: 1105ms (약 1.1초)
  • 오류 없음
  • JSON 데이터 반환

항목명 의미

Thread Name: Thread Group 1-5 5번째 사용자 (스레드)
Sample Start: 2025-05-10 15:57:58 KST 요청 시작 시각
Load time: 1105 요청부터 응답까지 걸린 총 시간 (ms) = 1.1초
Connect Time: 0 서버와 연결까지 걸린 시간 (ms)→ 이미 Keep-Alive 상태거나 너무 빨라서 0
Latency: 1104 서버에서 첫 응답 바이트를 받기까지 걸린 시간
Size in bytes: 674 응답 전체 크기 (헤더 + 바디)
Sent bytes: 128 요청 시 전송된 총 바이트
Headers size in bytes: 386 응답 헤더 크기
Body size in bytes: 288 응답 바디(JSON) 크기
Sample Count: 1 테스트 건수 (이 요청 1건)
Error Count: 0 오류 없음 (성공)
Data type: text 응답 데이터 타입 (text, 즉 일반 텍스트)
Response code: 200 HTTP 상태 코드 - OK
Response message: (빈 값) 응답 메시지 (일반적으로 "OK" 등인데 빈 값도 있음)
ContentType: application/json 응답 콘텐츠 형식 (JSON)
DataEncoding: null 문자 인코딩 명시 없음

개선 포인트

원인 가능성 개선 방안

 

이미지 처리 오래 걸림 비동기 처리 (@Async)
서버 처리량 부족 Thread 수 조정, Tomcat 설정 변경
DB 처리 지연 쿼리 튜닝, Index 확인
정적 파일 처리 포함 CDN 또는 외부 이미지 서버 분리
중복 처리 발생 Redis 등으로 캐싱 도입

사실상 새로운 데이터를 전송하는 것이기 때문에

 

우선순위 개선 항목 이유

 1 캐시 적용 (Redis or 정적 파일 서버) 한번 저장된 이미지는 다시 생성할 필요 없이 바로 응답 가능 → 서버 부하 크게 감소
 2 비동기 처리 도입 (@Async) 초기 업로드 처리 속도 개선, 사용자 체감 속도 향상
3 DB 튜닝 이미지 메타데이터 처리 과정에서 병목 있으면 추가 개선

 

왜 캐시가 1순위인가?

  • 이미지 업로드는 드물고 한 번, 이후엔 거의 GET 요청 반복
  • 이럴 땐 @Async로 처음 저장을 빨리 해주는 것도 중요하지만,
    캐시나 정적 파일 서버(CDN 등)에 올려서
    “한 번 처리한 이미지”는 다시 처리하지 않고 바로 제공하는 것이 가장 효과적이라고 생각했음.
  • 업로드 완료 후 이미지 URL 캐싱 또는 S3 같은 정적 서버에 올리기
    → 클라이언트는 그 URL만 요청

근데 사실 현재 외주 진행사항이 -> 어떤 이미지가 올라갈지 확정짓지 않았기 떄문에 MVP개발 후 배포 시 Redis를 적용하는 것이 올바르다고 생각이 들고있음.

 

728x90