o2o-negosium-original/lps/run_loadtest_gui.sh
민헌 0e30354ba5 feat(lps): 로컬 워커·부하테스트(GUI) 실행 스크립트 추가 (대화형)
기존 run_local_server.sh 스타일에 맞춘 대화형 .sh 두 개.

- run_local_worker.sh: 동시성(WORKER_CONCURRENCY)·Chrome 프로필(LPS_PROFILE_DIR)
  선택 후 워커 기동. 실행 중 워커 감지 시 교체 여부 확인. venv/config 자동 보장.
- run_loadtest_gui.sh: Locust 웹 UI(:8089) 기동. 워커 실행 중이면 경고(크롤 비용),
  API 미기동 시 PROCESS_COUNT 받아 백그라운드 기동(종료 시 함께 정리). 부하생성기 --processes.
- .gitignore(lps): .profiles/(Chrome 쿠키·cf_clearance 세션) 커밋 방지
- README·operations: 새 스크립트 안내로 갱신

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 08:33:11 +09:00

85 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# LPS 부하 테스트 — Locust 웹 UI(GUI) 실행 (대화형).
# 브라우저(:8089)에서 동시 유저 수·spawn rate 를 조절하며 실시간 그래프로 RPS/지연을 본다.
# 대상 = API 서버(web_main, :9600). enqueue/조회 경로에 부하를 준다.
#
# ⚠️ 워커는 끄고 실행하라 — 부하 중 실제 크롤(프록시/AI 비용)이 발생한다.
# 쌓인 부하 잡 정리: psql -h 127.0.0.1 -U postgres -d lps_db -c "TRUNCATE job;"
#
set -euo pipefail
cd "$(dirname "$0")" # lps/
VENV=".venv"
PY="$VENV/bin/python"
LOCUST="$VENV/bin/locust"
HOST="http://localhost:9600"
PORT=9600
WEBUI_PORT=8089
# 1) venv + locust 보장
if [[ ! -d "$VENV" ]]; then
echo "[setup] venv 생성 + 의존성 설치..."
python3 -m venv "$VENV"
"$PY" -m pip install -q --upgrade pip
"$PY" -m pip install -q -r requirements.txt
fi
if [[ ! -x "$LOCUST" ]]; then
echo "[setup] locust 설치..."; "$PY" -m pip install -q locust
fi
# 2) 워커가 떠 있으면 경고(부하 중 실제 크롤=비용)
if pgrep -f worker_main.py >/dev/null 2>&1; then
echo "[warn] 워커(worker_main.py)가 실행 중입니다 — 부하 중 실제 크롤 비용(프록시/AI)이 발생합니다."
read -rp " 워커를 종료할까요? [Y/n]: " k
[[ "${k:-Y}" =~ ^[Nn] ]] || { pkill -f worker_main.py || true; sleep 1; echo " 워커 종료"; }
fi
# 3) API 기동 확인 — 없으면 띄울지 물어본다
API_STARTED=""
if curl -s "$HOST/healthz" >/dev/null 2>&1; then
echo "[info] API 서버 감지됨 ($HOST)"
else
echo "[info] API 서버($HOST)가 응답하지 않습니다."
read -rp " 이 스크립트가 API 를 띄울까요? [Y/n]: " s
if [[ ! "${s:-Y}" =~ ^[Nn] ]]; then
read -rp " 멀티코어 PROCESS_COUNT [1] (풀은 자동 산정): " PC; PC="${PC:-1}"
echo " [run] web_main.py (PROCESS_COUNT=$PC) 백그라운드 기동..."
PROCESS_COUNT="$PC" APP_ENV=local "$PY" web_main.py > /tmp/lps_api_loadtest.log 2>&1 &
API_STARTED=$!
for _ in $(seq 1 20); do curl -s "$HOST/healthz" >/dev/null 2>&1 && break; sleep 1; done
if curl -s "$HOST/healthz" >/dev/null 2>&1; then
echo " API 기동 완료 (로그: /tmp/lps_api_loadtest.log)"
else
echo " [error] API 기동 실패 — /tmp/lps_api_loadtest.log 확인"; kill "$API_STARTED" 2>/dev/null || true; exit 1
fi
else
echo " [안내] 먼저 다른 터미널에서 ./run_local_server.sh 로 API 를 띄우세요."; exit 1
fi
fi
# 4) 부하 생성기 멀티프로세스(locust 자체가 병목되지 않게). 코어 많으면 늘린다.
CORES=$("$PY" -c "import os;print(os.cpu_count())")
read -rp "부하 생성기 프로세스 수 --processes [4] (CPU=$CORES): " LP; LP="${LP:-4}"
# API 를 이 스크립트가 띄웠으면 종료 시 함께 내린다
cleanup() { [[ -n "$API_STARTED" ]] && { echo ""; echo "[info] 스크립트가 띄운 API 종료"; kill "$API_STARTED" 2>/dev/null || true; }; }
trap cleanup EXIT
echo ""
echo "════════════════════════════════════════════════════════"
echo " Locust 웹 UI: http://localhost:$WEBUI_PORT"
echo " 대상 API : $HOST"
echo " → 브라우저에서 users/spawn rate 입력 후 START"
echo " 중단: Ctrl+C · 끝나면 쌓인 잡 정리:"
echo " psql -h 127.0.0.1 -U postgres -d lps_db -c 'TRUNCATE job;'"
echo "════════════════════════════════════════════════════════"
echo ""
# API 를 이 스크립트가 띄웠으면 exec 하지 않는다(종료 시 trap 으로 API 를 함께 내리기 위해).
if [[ -n "$API_STARTED" ]]; then
"$LOCUST" -f loadtest/locustfile.py --host "$HOST" --web-port "$WEBUI_PORT" --processes "$LP"
else
exec "$LOCUST" -f loadtest/locustfile.py --host "$HOST" --web-port "$WEBUI_PORT" --processes "$LP"
fi