성능 최적화 10편 - JMeter로 부하 테스트하고 개선 효과 검증하기
지금까지 Fetch Join, @BatchSize, Redis 캐싱, 인덱스, 분산 락, 커넥션 풀, APM, 비동기 처리까지 다양한 최적화 기법을 다뤘습니다. 하지만 이 모든 작업의 효과는 "느낄 것 같다"가 아니라 숫자로 검증되어야 합니다. 이번 글에서는 JMeter로 부하 테스트를 수행하고, 최적화 전후를 비교하는 방법을 정리합니다.
1. 부하 테스트가 필요한 이유
- 개발 환경에서는 데이터가 적고 요청도 하나씩 들어와서, 실제 운영에서 발생하는 동시 접속 상황을 재현하기 어렵습니다.
- 최적화를 적용했다고 해도, 실제로 몇 배나 빨라졌는지, 어느 트래픽 수준부터 다시 느려지는지는 테스트 없이는 추측에 불과합니다.
- 배포 전에 병목을 미리 발견하면, 장애로 이어지기 전에 대응할 수 있습니다.
2. JMeter 기본 구성
JMeter는 Thread Group을 기준으로 가상 사용자 수, 요청 반복 횟수, 부하를 끌어올리는 시간을 설정합니다.
Thread Group
├─ Number of Threads (동시 사용자 수): 100
├─ Ramp-up Period (초): 10
└─ Loop Count (반복 횟수): 10
- Number of Threads : 동시에 요청을 보낼 가상 사용자 수
- Ramp-up Period : 설정한 사용자 수까지 도달하는 데 걸리는 시간 (한 번에 몰아치지 않고 서서히 늘림)
- Loop Count : 각 사용자가 요청을 반복하는 횟수
3. HTTP 요청 시나리오 구성
HTTP Request
├─ Method: GET
├─ Path: /api/orders/${orderId}
└─ Server Name: localhost, Port: 8080
CSV 파일로 여러 orderId를 미리 준비해두고, CSV Data Set Config로 요청마다 다른 값을 사용하도록 구성하면 실제 트래픽과 더 유사하게 테스트할 수 있습니다.
CSV Data Set Config
├─ Filename: order_ids.csv
└─ Variable Names: orderId
4. 결과 지표 확인하기
테스트 실행 후 Summary Report나 Aggregate Report에서 다음 지표를 확인합니다.
Label # Samples Average Min Max Error % Throughput
GET /orders 1000 850ms 120 2400 0.0% 95/sec
- Average : 평균 응답 시간
- Min / Max : 가장 빠른/느린 응답 시간
- Error % : 실패한 요청의 비율
- Throughput : 초당 처리 가능한 요청 수
여러 지표 중에서도 평균값보다 p95, p99(상위 5%, 1% 느린 요청 기준)를 함께 보는 것이 중요합니다. 평균은 낮아도 일부 요청이 심하게 느리다면, 사용자 체감 품질은 나쁠 수 있기 때문입니다.
5. 최적화 전후 비교하기
지금까지 다룬 최적화를 적용하기 전과 후의 결과를 나란히 비교하면 개선 효과를 명확히 보여줄 수 있습니다.
[최적화 전] N+1 문제 + 캐싱 없음 + 인덱스 없음
Average: 1200ms p99: 3500ms Error: 2.1% Throughput: 42/sec
[최적화 후] Fetch Join + Redis 캐싱 + 인덱스 적용
Average: 180ms p99: 420ms Error: 0.0% Throughput: 210/sec
이렇게 수치로 비교하면, 어떤 최적화가 실제로 효과가 있었는지 근거를 가지고 설명할 수 있습니다.
6. 부하 테스트 시 주의할 점
- 운영 환경에서 직접 테스트하지 않는다. 실제 트래픽과 섞이면 서비스 장애로 이어질 수 있어, 별도의 스테이징 환경에서 진행하는 것이 안전합니다.
- DB 데이터도 운영과 유사한 규모로 준비한다. 데이터가 몇 건 없는 상태에서는 인덱스나 캐싱 효과가 왜곡되어 나타납니다.
- 점진적으로 부하를 늘린다. 처음부터 최대 트래픽을 쏘기보다, Ramp-up을 활용해 서서히 늘리면서 어느 시점부터 성능이 무너지는지(임계점) 확인합니다.
- 테스트 중 APM을 함께 확인한다. 8편에서 다룬 APM을 부하 테스트와 함께 켜두면, 부하가 몰릴 때 어느 구간이 먼저 느려지는지 실시간으로 확인할 수 있습니다.
7. 정리
- 최적화의 효과는 감이 아니라 부하 테스트를 통한 수치로 검증해야 한다
- JMeter의 Thread Group으로 동시 사용자 수와 부하 증가 패턴을 설정하고, Aggregate Report로 응답 시간과 에러율을 확인한다
- 평균값뿐 아니라 p95, p99 같은 상위 퍼센타일 지표까지 함께 살펴봐야 실제 사용자 체감을 정확히 파악할 수 있다
- 부하 테스트는 스테이징 환경에서, 운영과 유사한 데이터 규모로 진행한다
이번 시리즈에서는 쿼리(Fetch Join, @BatchSize), 캐싱(Redis), 데이터베이스(인덱스, 분산 락), 인프라(커넥션 풀), 관측(APM), 처리 방식(비동기)까지 성능 최적화를 여러 층위에서 다뤄봤습니다. 결국 성능 최적화는 한 가지 기법으로 끝나는 것이 아니라, 병목을 정확히 찾아내고(APM, 부하 테스트) 해당 지점에 맞는 전략을 적용하는 반복적인 과정이라는 것을 정리하며 이번 시리즈를 마무리 하겠습니다.
'성능 최적화' 카테고리의 다른 글
| 성능 최적화 STEP 12 - No Offset (0) | 2026.07.09 |
|---|---|
| 성능 최적화 STEP 11 - Kafka로 무거운 작업 비동기 분리하기 (0) | 2026.07.09 |
| 성능 최적화 STEP 9 - @Async와 CompletableFuture로 비동기 처리하기 (0) | 2026.07.08 |
| 성능 최적화 STEP 8 - APM으로 병목 구간 추적하기 (0) | 2026.07.07 |
| 성능 최적화 STEP 7 - HikariCP 커넥션 풀 튜닝으로 DB 병목 줄이기 (0) | 2026.07.07 |