카카오테크 부트캠프/프로젝트

웹서비스 부하 테스트

bubhyun 2025. 5. 16. 14:47
728x90

부하 테스트 시나리오 구성

시나리오 1: 10초간 150명의 사용자가 해설 요청

  • API: GET /api/problems/:id/solution
  • 목적: 동시에 많은 사용자가 특정 문제의 해설을 요청할 때, 응답 지연이나 병목이 있는지 확인
  • 설정 방식: Classic Thread Group으로 num_threads=150, ramp_time=10 설정 → 적절함
  • 개선 제안:
    • 실제 요청에 :id 대신 특정 문제 ID (예: /api/problems/123/solution)를 고정하거나, CSV Data Set Config를 통해 ID 목록을 랜덤 요청하도록 개선 가능
<TestPlan>
  <ThreadGroup num_threads="150" ramp_time="10" loops="1">
    <HTTPSamplerProxy method="POST" path="/api/explanation">
      <elementProp name="HTTPsampler.Arguments">
        <!-- JSON 요청 본문 -->
      </elementProp>
    </HTTPSamplerProxy>
    <HeaderManager>
      <Header name="Content-Type" value="application/json"/>
    </HeaderManager>
  </ThreadGroup>
</TestPlan>

시나리오 2: 10초간 150명의 사용자가 로그인 요청

  • API: (추가 필요 – 예: POST /api/auth/login)
  • Thread Group 유형: Step Thread Group 사용 → 점진적 로그인 부하 테스트에 매우 적합
  • 개선 제안:
    • 로그인 요청은 보통 POST이므로, 사용자 계정 정보가 필요합니다.
    • CSV 파일 또는 User Defined Variables로 계정 150개를 순차 또는 랜덤 사용하도록 구성하면 현실적입니다.
    • 비밀번호 실패/성공 케이스도 구분 가능
<kg.apc.jmeter.threads.SteppingThreadGroup guiclass="kg.apc.jmeter.threads.SteppingThreadGroupGui" testclass="kg.apc.jmeter.threads.SteppingThreadGroup" testname="Step Thread Group" enabled="true">
  <stringProp name="ThreadGroup.num_threads">200</stringProp>
  <stringProp name="ThreadGroup.ramp_time">0</stringProp>
  <longProp name="StartUsersCount">20</longProp>
  <longProp name="StartUsersCountBurst">20</longProp>
  <longProp name="StartUsersPeriod">10</longProp>
  <longProp name="StepCount">10</longProp>
  <longProp name="HoldTime">30</longProp>
  <longProp name="FlightTime">0</longProp>
  <boolProp name="StepByStep">false</boolProp>
  <elementProp name="TestPlan.user_define_classpath" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true">
    <collectionProp name="Arguments.arguments"/>
  </elementProp>
</kg.apc.jmeter.threads.SteppingThreadGroup>

시나리오 3: 사용자 증가에 따른 부하 증가 (점진적 부하)

  • API: GET /api/problems/:id/solution (시나리오 1과 같은 엔드포인트)
  • Thread Group: Step Thread Group (사용자 수 점진 증가)
  • 목적: 병목 구간, 최대 동시 사용자 수 확인에 적합
  • 개선 제안:
    • 동일 API라도 요청 파라미터 다양화를 고려 (예: 여러 id값 사용)
    • 요청 응답에 대한 임계점 분석을 위해 TPS, 평균 응답 시간 그래프 확인 필요
<kg.apc.jmeter.threads.SteppingThreadGroup>
  <stringProp name="NumThreads">200</stringProp>
  <stringProp name="StartUsersCount">20</stringProp>
  <stringProp name="InitialDelay">0</stringProp>
  <stringProp name="StartUsersCountBurst">20</stringProp>
  <stringProp name="StartUsersPeriod">10</stringProp>
  <stringProp name="StepCount">10</stringProp>
  <stringProp name="HoldTime">30</stringProp>
</kg.apc.jmeter.threads.SteppingThreadGroup>

응답에서 확인할 항목

  • 응답 속도 평균/최대/최소
  • 5xx 에러 발생률 (서버 오류)
  • DB 쿼리 시간 (로그 또는 slow query 분석)
  • 메모리/CPU 사용량 (CloudWatch, Grafana 등으로 모니터링)

예측 가능한 이슈

API 병목 DB join 과다 사용시 응답 지연 가능 (problem + solution + user_detail)
캐시 미적용 같은 문제 해설 요청시 DB 계속 조회
해설 미존재 시 오류 처리 null 반환 시 404 또는 빈 해설 처리 필요

 

부하테스트 실습 구성

- 필수 구성 요소 설치

1. Java (JMeter 실행용)

sudo apt update
sudo apt install openjdk-17-jdk -y
java -version

2. JMeter 설치(로컬)

wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-5.6.3.tgz
tar -xzf apache-jmeter-5.6.3.tgz
sudo mv apache-jmeter-5.6.3 /opt/jmeter

3. InfluxDB 설치(서버)

wget -qO- <https://repos.influxdata.com/influxdb.key> | sudo gpg --dearmor -o /usr/share/keyrings/influxdb-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/influxdb-archive-keyring.gpg] <https://repos.influxdata.com/ubuntu> $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
sudo apt update
sudo apt install influxdb -y

4. Grafana 설치(서버)

sudo apt install -y apt-transport-https software-properties-common curl gnupg

# GPG 키 저장
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://packages.grafana.com/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/grafana.gpg

# Grafana 저장소 등록
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list

# 패키지 목록 업데이트 및 설치
sudo apt update
sudo apt install grafana -y

서비스 실행

sudo systemctl start influxdb
sudo systemctl enable influxdb

sudo systemctl start grafana-server
sudo systemctl enable grafana-server

Influx DB 쓴 이유:

JMeter + Prometheus = 직접 연동은 어렵고, 비표준적인 방법 필요

이유

  • Prometheus는 Pull 방식이라 JMeter가 메트릭을 직접 전달(push)하지 못함
  • JMeter 자체에 Prometheus exporter가 없음
  • 대신, 다음과 같은 우회적인 방법을 사용해야 함:
    • JMeter → StatsD → Prometheus exporter
    • JMeter 결과를 로그로 저장 후 Exporter 형식으로 변환하여 노출
    • 커스텀 Exporter를 만들어 Prometheus가 긁어가게 구성

결론

  • 비효율적이며 번거롭고 실시간성이 떨어짐
  • 실시간 수집/시각화를 원한다면 적합하지 않음

InfluxDB 설정

sudo apt install influxdb-client
influx

DB 생성

CREATE DATABASE jmeter;
exit

 


JMeter 설정

Backend Listener 추가 (GUI 또는 수동)

  1. JMeter 실행:
/opt/jmeter/bin/jmeter
  1. Test Plan(우클릭) → Add → Listener → Backend Listener
  2. 설정 값 입력:
항목
Backend Listener Implementation InfluxdbBackendListenerClient
Parameters influxdbMetricsSender=org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender
influxdbUrl=http://43.202/123/45:8086/write?db=jmeter
application=jmeter
measurement=stress
summaryOnly=false
samplersRegex=.*


Grafana 설정

웹 브라우저 접속:

http://43.202.239.246:3000
  • 기본 로그인: admin / admin

InfluxDB 데이터 소스 추가:

  1. Connections → Data Sources → Add data source
  2. InfluxDB 선택
  3. 설정 값:
URL http://localhost:8086
Database jmeter
HTTP Method GET
Query Language InfluxQL
Min Time Interval 1s

→ Save & Test 클릭


Grafana 대시보드 구성

방법 1: 직접 생성

  • Dashboard → New → Add Panel
  • Query 예시:
SELECT mean("value") FROM "responseTime" WHERE $timeFilter GROUP BY time($__interval)

방법 2: 템플릿 가져오기 (추천)

  • Grafana 메뉴 → Import dashboard
  • ID 입력: 5496 → JMeter용 템플릿 로딩
  • 데이터소스: jmeter 선택


결과 확인 항목

  • 평균 응답 시간 / 최대값 / 에러율
  • TPS (초당 처리 요청 수)
  • Active Threads (동시 사용자 수)
  • 특정 샘플러별 성능 분포

 

728x90