MVP 대규모 동시접속 부하테스트 - JMeter

smj_716·2025년 6월 29일

한이음 드림업

목록 보기
5/9

1. 테스트 개요

수천 명 이상이 동시에 몰리는 수강신청 상황에서 시스템이 다운되지 않고 얼마나 잘 버티는지, 특히 제한된 자원(t3.large) 환경에서 얼마만큼의 트래픽을 처리할 수 있는지를 보기 위해 이번 테스트를 진행햇다.

👉이 시스템은 다음과 같은 특성이 있다:

  • 짧은 시간 내 폭발적인 접속
  • 실시간 좌석 정보와 동기성 중요
  • 백엔드 성능이 느려지면 사용자 불신이 직접적으로 이어짐

👉 테스트 아키텍처

  • 백엔드: Spring Boot
  • 웹 서버: Nginx
  • DB: Amazon RDS (MySQL)
  • 캐시: Redis (후속 도입 예정)
  • 메시지 브로커: Kafka (후속 도입 예정)
  • 서버 인프라: EC2 t3.large (2vCPU, 8GiB RAM)
  • 테스트 도구: Apache JMeter + Puppeteer (브라우저 기반 시뮬레이션)

이번 글은 MVP 구조에서의 테스트만 다루며 이후 보완된 단계는 별도 포스트로 기록할 예정이다.

📢 테스트의 성능 측정 결과는 JMeter에서 수집된 데이터를 기반으로 HTML 리포트로 시각화해 확인했다.
각 요청별 응답시간 분포, 실패율, TPS, 네트워크 전송량 등 지표를 정량적으로 비교할 수 있었다.
아래는 실제 리포트 시각화 예시 캡처 이미지이다.


2. 시나리오 구성

테스트는 총 6가지 인원 케이스(100 / 1,000 / 3,000 / 5,000 / 7,000 / 10,000명)로 나누어 수행했고, 아래 5가지 핵심 시나리오를 중심으로 구성했다:

  • ENROLL_1: 로그인 유지 부하
  • ENROLL_2: 특정 교양 강의 신청 집중
  • ENROLL_3: 서로 다른 전공 그룹이 각각 하나의 전공 강의 신청
  • ENROLL_4: 3조건에서 신청 -> 취소 반복
  • ENROLL_5: 다수 전공 그룹이 다수 강의에 대한 분산 신청

3. 실험별 상세 분석

100명~1,000명까지는 비교적 안정적이었지만 3,000명 이상부터 502 Bad Gateway 오류가 급증했고, 10,000명 접속 시 실패율은 83.54%에 달했으며 대부분 Timeout 또는 서버 내부 오류였다.

502는 Spring Boot 백엔드가 응답을 제때 주지 못해 Nginx가 대신 에러를 반환한 것으로 500 오류는 내부 Thread Pool 포화 혹은 HikariCP 커넥션 부족이 원인으로 보였다.

➡️ Nginx worker_connections 변화

Nginx에서 worker_connections란?
클라이언트의 요청을 처리하는 동시 연결 수를 조절하는 값이다.
이 숫자가 작으면 많은 유저가 몰릴 경우 요청이 차단되거나 지연된다.

  • worker_connections 값을 768 → 4096으로 증가시키며 테스트
  • 결과: 502 오류율은 점진적으로 감소했지만 전체 실패율은 91~93%로 유사함
  • 이유: Nginx 입구는 넓어졌지만 백엔드(Spring+DB) 병목은 여전했기 때문

📌 정리하면, Nginx 튜닝은 효과가 있지만 입구만 뚫린 상태로 내부 문제는 여전했다.

➡️ Spring Thread Pool 실험

Thread Pool이란?
애플리케이션에서 동시에 여러 요청을 처리할 수 있도록 해주는 작업 스레드 모음이다. 너무 작으면 처리 병목이 생기고, 너무 크면 시스템 자원과 충돌한다.

  • Thread Pool 크기를 200 → 300 → 400으로 늘려가며 평균 응답 시간, TPS(초당 처리 수), CPU 점유율, 실패율을 측정
  • 결과: Thread 수 증가에도 불구하고 평균 응답시간은 늘고 TPS는 감소함
  • 이유: Spring Boot 애플리케이션 내부 Thread가 동시 처리할 수 있는 요청을 늘어났지만, DB 커넥션 풀이 부족해 Thread는 대기만 하게 됨

📌 결론: Thread만 늘리면 오히려 병목 심화됨 → 반드시 DB Connection Pool과 함께 조정해야 함

➡️ DB 커넥션 풀 (HikariCP) 실험

DB 커넥션 풀(HikariCP)이란?
DB와 연결할 수 있는 커넥션들을 미리 만들어 풀(Pool) 형태로 관리하는 구조다. 필요할 때 커넥션을 즉시 꺼내 쓸 수 있어 빠르고 효율적이다.

  • active 커넥션: 현재 DB와 연결되어 사용 중인 커넥션 수
  • idle 커넥션: 아직 사용되지 않고 대기 중인 커넥션 수
  • waiting: 커넥션을 받기 위해 대기 중인 요청 수
  • Pool size = 10일 때
    • Active 10 / Idle 0 / Waiting 190 (타임아웃 다수 발생)
  • Pool size = 100일 때
    • Active 99 / Idle 1 / Waiting 6 (안정적 처리 가능)

커넥션 풀이 부족하면 Thread는 살아 있어도 DB 연결을 못 받아 대기 상태로 빠지고
이로 인해 TPS 하락, 응답 시간 증가, 502/500 오류 증가로 이어졌다.

📌 결론: 적절한 커넥션 풀 확보만으로도 전체 시스템 안정성이 비약적으로 향상됨


4. 요약

  • Thread만 늘리는 방식은 오히려 지연을 초래했고 DB와 함께 튜닝해야 했다
  • Nginx 튜닝은 입구 처리량은 높였지만 백엔드 병목 해결에는 역부족이었다

🌟 결론적으로 현재 구조(MVP)에서는 3,000명 이상의 동시 접속에서 시스템 안정성 확보가 어렵다는 것을 실험으로 확인했고 비동기 구조 도입 없이는 이 한계를 넘기 어렵다고 판단했다.

0개의 댓글