#!/usr/bin/env bash # ===================================================================== # LiveKit 부하 테스트 러너 (화상회의 단계 5: 확장 검증) # --------------------------------------------------------------------- # livekit-cli(lk load-test)로 가상 publisher/subscriber 를 대량 접속시켜 # SFU 의 부하·미디어 품질(지연/패킷손실/대역폭)을 측정한다. # # 사용법: # ./livekit/load-test.sh [preset] # preset: smoke(기본) | medium | full # # 세부 조정(환경변수로 덮어쓰기): # ROOM, PUBLISHERS, SUBSCRIBERS, DURATION, RESOLUTION(low|medium|high), # LAYOUT(speaker|3x3|4x4|5x5), SIMULCAST(on|off), NUM_PER_SECOND # # 자격증명은 루트 .env.${APP_ENV:-development} 에서 읽는다 # (LIVEKIT_URL / LIVEKIT_API_KEY / LIVEKIT_API_SECRET). # # ⚠️ 주의: # - 대규모(full=160참여자) 테스트는 반드시 "셀프호스팅 LiveKit(단계 6)" 또는 # 전용 테스트 인스턴스를 대상으로 실행하세요. # - LiveKit Cloud 무료/개발 티어에 대한 대량 부하는 동시 접속 쿼터 초과 및 # 이용약관 위반 소지가 있습니다. Cloud 에서는 smoke(소규모)로 도구 검증만 하세요. # - 부하 분산(클러스터링) 검증은 SFU 노드가 2개 이상인 셀프호스팅 구성에서만 의미가 있습니다. # ===================================================================== set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env.${APP_ENV:-development}}" PRESET="${1:-smoke}" # 프리셋별 기본값(환경변수가 있으면 그것을 우선) case "$PRESET" in smoke) PUBLISHERS="${PUBLISHERS:-2}"; SUBSCRIBERS="${SUBSCRIBERS:-3}" DURATION="${DURATION:-15s}"; RESOLUTION="${RESOLUTION:-low}"; LAYOUT="${LAYOUT:-3x3}" ;; medium) PUBLISHERS="${PUBLISHERS:-5}"; SUBSCRIBERS="${SUBSCRIBERS:-30}" DURATION="${DURATION:-1m}"; RESOLUTION="${RESOLUTION:-medium}"; LAYOUT="${LAYOUT:-5x5}" ;; full) # 문서 목표: 최대 160명(진행자 소수 발행 + 다수 구독), 동시 표시 ~50명 PUBLISHERS="${PUBLISHERS:-10}"; SUBSCRIBERS="${SUBSCRIBERS:-150}" DURATION="${DURATION:-2m}"; RESOLUTION="${RESOLUTION:-high}"; LAYOUT="${LAYOUT:-speaker}" ;; *) echo "알 수 없는 preset: $PRESET (smoke|medium|full)" >&2; exit 1 ;; esac ROOM="${ROOM:-loadtest-$PRESET}" NUM_PER_SECOND="${NUM_PER_SECOND:-5}" SIMULCAST="${SIMULCAST:-on}" SIMULCAST_FLAG=() [ "$SIMULCAST" = "off" ] && SIMULCAST_FLAG=(--no-simulcast) # .env 에서 필요한 값만 읽는다(CRLF 제거). 파일이 없으면 기존 환경변수 사용. read_env() { if [ -f "$ENV_FILE" ]; then grep -E "^$1=" "$ENV_FILE" | tail -1 | cut -d= -f2- | tr -d '\r' fi } export LIVEKIT_URL="${LIVEKIT_URL:-$(read_env LIVEKIT_URL)}" export LIVEKIT_API_KEY="${LIVEKIT_API_KEY:-$(read_env LIVEKIT_API_KEY)}" export LIVEKIT_API_SECRET="${LIVEKIT_API_SECRET:-$(read_env LIVEKIT_API_SECRET)}" if [ -z "${LIVEKIT_URL:-}" ] || [ -z "${LIVEKIT_API_KEY:-}" ] || [ -z "${LIVEKIT_API_SECRET:-}" ]; then echo "LIVEKIT_URL / LIVEKIT_API_KEY / LIVEKIT_API_SECRET 를 찾을 수 없습니다 ($ENV_FILE)." >&2 exit 1 fi echo "▶ LiveKit load-test [$PRESET]" echo " URL=$LIVEKIT_URL ROOM=$ROOM" echo " publishers=$PUBLISHERS subscribers=$SUBSCRIBERS duration=$DURATION resolution=$RESOLUTION layout=$LAYOUT simulcast=$SIMULCAST" echo # livekit-cli(lk)는 $LIVEKIT_URL/$LIVEKIT_API_KEY/$LIVEKIT_API_SECRET 를 자동으로 읽는다. docker run --rm \ -e LIVEKIT_URL -e LIVEKIT_API_KEY -e LIVEKIT_API_SECRET \ livekit/livekit-cli load-test \ --room "$ROOM" \ --duration "$DURATION" \ --publishers "$PUBLISHERS" \ --subscribers "$SUBSCRIBERS" \ --video-resolution "$RESOLUTION" \ --layout "$LAYOUT" \ --num-per-second "$NUM_PER_SECOND" \ "${SIMULCAST_FLAG[@]}"