실시간 부하 테스트 계획과 실제 수행
1. 테스트 목표
본 프로젝트의 핵심인 실시간성(Mediasoup, Socket.io)을 보장하기 위해 다음과 같은 구체적인 성능 목표를 설정했습니다.
- 동시 접속자: 총 150명 (마스터 1명 + 학생 149명)
- 응답 시간 (Latency):
- 시그널링(방 입장 등): 500ms 이내
- 데이터(제스처 공유): 100ms 이내 지연 유지
- 미디어 품질: 패킷 손실(Packet Loss) 2% 미만 유지
- 서버 자원: 미디어 워커(Worker) 프로세스 기준 CPU 사용률 70% 미만 유지
2. 테스트 단계
부하를 점진적으로 강화하며 시스템의 안정성을 다각도로 검증할 계획입니다.
- 단위 부하 테스트: 채팅, 투표, 제스처 등 단일 기능별로 부하를 주어 개별 로직의 병목을 확인합니다.
- 임계치 테스트: 접속자 수를 점진적으로 늘려 서버가 감당 가능한 최대 한계를 측정합니다.
- 스트레스 테스트: 목표치인 150명 수준의 트래픽을 1시간 이상 장기 유지하며, 메모리 누수나 장기 가동 시의 안정성을 확인합니다.
3. 부하 테스트 도구 리서치
Nest.js, Mediasoup, React 스택에 최적화된 도구를 찾기 위해 총 6가지 후보군을 검토했습니다.
3.1. k6 (+ WebTRC 플러그인)
- 작동 원리
- Go 기반 부하 엔진 위에서 스크립트(Javascript)를 실행하여 가상 사용자(VU)를 생성하고, HTTP/WebSocket 등 다양한 프로토콜에 부하를 발생시킵니다.
- WebRTC 전용 플러그인을 통해 PeerConnection을 시뮬레이션하여 미디어 스트림 송수신 부하를 줄 수 있는 확장도 존재합니다.
- 장점
- 가벼운 런타임으로 수백~수천 VU를 단일 노드에서 운영 가능해 리소스 효율이 매우 높다.
- 시나리오를 코드로 작성하므로 버전 관리 및 리뷰가 용이하며, 외부 모니터링/대시보드 시스템과 연동이 수월합니다.
- 단점
- 실제 브라우저를 구동하지 않으므로 DOM·Canvas·MediaPipe와 같은 렌더링/클라이언트 CPU 부하는 측정할 수 없습니다.
- 적합도 (본 프로젝트 기준)
- Mediasoup SFU에 대한 미디어 트래픽 부하, 임계치 테스트 및 장시간 스트레스 테스트의 주력 도구로 적합해보입니다.
3.2. Artillery
- 작동 원리
- Node.js 기반 경량 부하 도구로, YAML 설정 파일과 JS 훅을 통해 HTTP·WebSocket·Socket.io 등의 시나리오를 정의합니다.
- 장점
- 설정이 단순하며, Socket.io용 전용 엔진이 존재해 실시간 이벤트 기반 서버(Nest.js Gateway)에 부하를 주기에 적합합니다.
- 특정 시간 동안의 도달 속도(도착률)와 사용자 수를 직관적으로 조절할 수 있어, “150명 동시 접속” 및 스파이크 패턴을 표현하기 쉽습니다.
- 단점
- WebRTC RTP/RTCP 미디어 트래픽을 직접 시뮬레이션하는 기능은 없으며, 데이터 채널·소켓 이벤트 중심의 테스트에 초점이 맞춰져 있습니다.
- 적합도 (본 프로젝트 기준)
- Nest.js 기반 시그널링/채팅/투표/제스처 데이터에 대한 단위 및 임계치 테스트에 매우 적합해 보입니다.
3.3. Playwright (e2e 테스트 기반)
- 작동 원리
- Chromium, Firefox, WebKit 등 실제 브라우저 엔진을 프로그램 코드로 직접 제어합니다. 사용자의 클릭, 입력뿐만 아니라 미디어 장치 접근(Fake Media)을 시뮬레이션하여 실제 웹 애플리케이션의 동작을 그대로 재현합니다.
- 장점
- 실제 렌더링 과정과 MediaPipe 연산 등 클라이언트 측 CPU 부하 및 체감 품질을 정확히 확인할 수 있습니다.
- 브라우저 내부에 JS 스크립트를 주입할 수 있어,
mediasoup-client와 같은 라이브러리를 직접 핸들링하며 테스트하기에 용이합니다.
- 단점
- 실제 브라우저 프로세스를 구동하기 때문에 메모리와 CPU 소모가 매우 큽니다. 단일 노드에서 생성할 수 있는 가상 사용자(VU) 수가 다른 도구에 비해 현저히 적습니다.
- 대규모 부하를 주려면 병렬 처리를 위한 고사양 인프라가 필수적입니다.
- 적합도 (본 프로젝트 기준)
- 수치적인 대량 부하 발생보다는, 실제 영상 끊김, 제스처 인식 품질 검증, 그리고 호스트(발표자)의 미디어 송출 자동화를 위한 핵심 보조 도구로 적합합니다.
3.4. JMeter (Aphache)
- 작동 원리
- Java 기반이며, 각 가상 사용자를 스레드로 생성하는 구조로 HTTP/DB 등 다양한 프로토콜을 지원합니다.
- 장점
- 오래된 도구로 문서·예제가 많고, GUI를 통해 복잡한 테스트 플랜을 시각적으로 구성할 수 있씁니다.
- 단점
- 스레드당 1유저 구조로 메모리 사용량이 큰 편이라 높은 동시 부하에 비효율적입ㄴ다.
- WebRTC나 최신 Socket.io 등에 대한 직접적인 지원이 부족해, 커스텀 플러그인/샘플러 개발이 필요합니다.
- 적합도 (본 프로젝트 기준)
- REST API 또는 DB 부하 측정 용도로는 사용할 수 있으나, 본 프로젝트의 핵심인 WebRTC + Socket.io 환경에는 효율적이지 않아 주력 도구에서 제외하는 것이 적절해보입니다.
3.5. Locust
- 작동 원리
- Python 기반 이벤트 루프를 활용해 사용자 행동 시나리오를 코드로 정의하고 실행하는 부하 테스트 도구
- 장점
- 순수 Python 코드로 사용자 여정을 작성할 수 있어, “로그인 → 방 입장 → 투표 → 채팅 → 퇴장”과 같은 복잡한 시퀀스를 표현하기에 적합합니다.
- 단점
- 인터프리터 특성상 동일한 부하를 처리하는 데 필요한 리소스가 Go 기반 도구보다 많을 수 있습니다.
- WebRTC를 부하 대상으로 삼으려면 별도 Python WebRTC 라이브러리를 직접 연동해야 하며, 구현 복잡도가 증가합니다.
- 적합도 (본 프로젝트 기준)
- 복잡한 행태 기반 시나리오가 꼭 필요할 때 보조 도구로 고려할 수 있으나, 현재 범위(150명, 미디어+제스처)에서는 우선 순위는 낮다고 판단됩니다.
3.6. The Grinder
- 작동 원리
- Java 기반 분산 부하 도구로, Jython 스크립트로 테스트를 작성하고 여러 에이전트에 분산 실행하는 구조입니다.
- 장점
- 분산 에이전트 관리와 스케일 아웃 관점에서 안정성이 검증된 도구입니다.
- 단점
- 최신 WebRTC, Socket.io 4.x 등 모던 실시간 기술 생태계와의 연동 레퍼런스가 부족하며, 커뮤니티 활동도 상대적으로 활발하지 않숩나더,
- 적합도 (본 프로젝트 기준)
- Mediasoup + Nest.js 구조에 직접적인 이점을 제공하지 못해 다른 도구에 비해 장점이 뚜렷하지 않습니다.
3.7. Taurus
- 작동 원리
- 여러 부하 도구(k6, JMeter, Selenium 등)를 통합 실행하는 추상화 레이어로, 하나의 YAML 설정으로 복수 도구를 동시에 구동할 수 있게 해준다.
- 장점
- “REST 부하는 A 도구, WebRTC 부하는 B 도구, 브라우저 e2e는 C 도구로 동시에 돌린다”와 같은 복합 시나리오를 단일 설정으로 관리할 수 있다.
- 리포팅 포맷이 일관되고, CI 파이프라인과 연계하기 좋은 구조를 제공한다.
- 단점
- 자체 엔진이 아니라, 결국 내부에서 다른 부하 도구가 설치·구성되어 있어야 한다.
- 적합도 (본 프로젝트 기준)
- k6와 Artillery, 브라우저 기반 테스트(Playwright/Selenium)를 동시에 orchestration하는 용도의 통합 컨트롤 타워로 적합합니다.
4. 최종 선정 도구 조합
실시간 제스처와 화상 통화라는 프로젝트의 특수성을 고려하여, 다음과 같이 역할별로 도구를 조합하여 사용하기로 결정했습니다. (2026.01.06 기준)
- k6 (+ WebRTC 플러그인): Mediasoup SFU에 대한 미디어 스트림 부하, 임계치 및 스트레스 테스트
- Artillery: Nest.js(Socket.io) 기반 시그널링, 채팅, 투표, 제스처 데이터 채널 부하
- Playwright: 실제 브라우저에서의 e2e 품질 검증(영상 끊김, 제스처 인식 체감 품질 등)
- Taurus: 위 도구들을 통합해 “실서비스와 유사한 복합 시나리오”를 단일 테스트로 실행
5. 실제 부하 테스트 수행 및 도구 최적화
리서치 단계에서는 k6를 메인 도구로 고려했으나, 실제 구현 과정에서 Artillery와 Playwright를 조합하는 방식으로 최종 결정하여 테스트를 진행했습니다. 계획과 실제 수행이 달라진 이유는 다음과 같습니다.
5.1. 도구 조합 변경 이유
- k6의 높은 구현 복잡도:
k6에서 WebRTC를 시뮬레이션하려면 Go 기반의 라이브러리를 직접 다뤄야 하는데, Mediasoup의 복잡한 시그널링과 미디어 전송 로직을 스크립트로만 재현하기에는 개발 공수가 너무 컸습니다. - Mediasoup 호환성: Mediasoup SFU 구조에 가장 최적화된 테스트를 위해, 실제 브라우저 엔진을 사용하는 방식이 더 정확하다고 판단했습니다.
5.2. 최종 수행 방법: 역할 분담 (Playwright + Artillery)
- 발표자(Host): Playwright 기반 스트림 송출
- 발표자는 실제 미디어 스트림을 생성해야 하므로, 실제 브라우저 환경을 제어하는 Playwright를 활용했습니다.
-use-fake-device-for-media-stream옵션을 사용하여 실제 카메라 없이도 Canvas와 AudioContext로 만든 가상 영상/음성을 송출했습니다.- 프론트엔드 페이지에
mediasoup-client와Socket.IO클라이언트를 직접 주입하여 실제 서비스와 동일한Producer생성 과정을 완벽히 재현했습니다.
- 청중(Audience): Artillery 기반 대규모 수신 시뮬레이션
- 다수의 청중은 Artillery의
processor기능을 통해 효율적으로 제어했습니다. - 시나리오: 강의실 생성(
ensureRoom) → 참가자 등록 → Socket.IO 연결 → WebRTC Transport 생성 및 실제 미디어 수신(Consume) 순서로 정교하게 설계했습니다. arrivalRate를 조절하여 1초에 1명씩 점진적으로 입장시키는 등 실제 서비스 상황과 유사한 트래픽 패턴을 구현했습니다.
- 다수의 청중은 Artillery의
6. 테스트 환경 구축의 한계와 고민
테스트를 준비하며 ‘부하를 어디서 발생시킬 것인가'에 대한 현실적인 문제에 직면했습니다.
- 로컬 환경의 한계: Playwright는 실제 브라우저를 구동하기 때문에 로컬 컴퓨터 한 대로는 150~200명의 부하를 감당하기에 리소스가 부족했습니다.
- 서버 환경의 시도와 실패: 부하 발생용 서버에 Playwright를 세팅하려 했으나, 브라우저 엔진 및 의존성 이미지 크기로 인해 서버 디스크가 가득 차는 문제가 발생했습니다.
- 기술적 타협과 분석:
- Fake Stream의 한계: Playwright에서 사용한 Fake Stream은 데이터 크기가 작아 실제 고해상도 영상의 네트워크 대역폭이나 CPU 부하를 완벽히 재현하기 어려웠습니다.
- 신뢰도 판단: 10~20명 단위의 테스트로 연결/라우팅/이벤트 처리는 검증되었으나, 실제 서비스 환경에서의 성능 한계치는 여전히 미지수로 남았습니다.
7. 테스트 수행 결과 및 지표 분석 (Phase 1)
Artillery를 통해 200명까지 접속했을 때, 서버(Backend)는 매우 안정적인 지표를 보였습니다.
| 항목 | 측정 값 | 비고 |
| Backend Memory | 144 MB | 메모리 누수 없이 안정적 |
| Backend CPU Usage | 2.26% | 소켓 및 라우팅 부하 미미 |
| HTTP P95 Response | 95 ms | 목표(500ms) 대비 매우 우수 |
| Redis Memory | 1.70 MB | 세션 데이터 관리 최적화 |
100명 접속시
150명 접속시
테스트 중 네트워크 수치가 예상보다 낮게 측정되었습니다. Playwright에서 사용한 Fake Stream의 특성상 실제 고해상도 영상 데이터보다 부하가 적었기 때문입니다. 10~20명 단위의 테스트로도 연결/라우팅/이벤트 처리는 충분히 신뢰할 수 있음을 확인했습니다.다만, 실제 네트워크 대역폭이나 영상 끊김, 극한의 CPU 부하를 측정하기에는 현재 수치를 그대로 믿기 어렵다는 한계를 인지했습니다.
8. 최종 결정: 공개 사용자 테스트 (Phase 2)
인위적인 시뮬레이션만으로는 실제 사용자들이 겪을 영상 끊김, 네트워크 대역폭 변화, 실제 디바이스의 CPU 부하를 완벽히 측정하기 어렵다고 판단했습니다. 이에 따라 실제 사용자를 초대하여 배포 환경에서 직접 테스트하는 방식을 택했습니다.
- 수행 내용: 실제 사용자들을 대상으로 공개 테스트를 진행하여 실전 환경의 미디어 송수신 품질을 검증했습니다.
- 기록 의미: 시뮬레이션으로 확인한 '시스템 안정성' 위에, 실제 유입된 트래픽을 통해 '서비스 품질'을 결합하여 데이터의 완성도를 높였습니다.
참고 자료
- https://blog.octoperf.com/ultimate-guide-23-free-load-testing-tools-reviewed/
- https://blog.yarsalabs.com/artillery-load-testing/
- https://www.artillery.io/blog/load-testing-socketio-with-artillery
- https://gettaurus.org/docs/Selenium/
- https://www.blazemeter.com/blog/testing-windows-applications-taurus-selenium
- https://mediasoup.discourse.group/t/load-testing-with-virtual-client-stream/2628
- https://github.com/versatica/mediasoup-broadcaster-demo
- https://github.com/arcas-io/arcas-load-test-mediasoup-example
- https://www.youtube.com/watch?v=fojCaHHJ6QY
Comments (0)
댓글을 불러오는 중...