⏰💡 Enroll 동시성 테스트 + 폴링 API 부하테스트 진행 방법(JMeter)

2026. 2. 15. 13:41·프로젝트/스프링 부트 3 백엔드 개발자 되기 Blog + 선착순 강의 프로젝트

🚨테스트 전에 꼭 해둘 것 3가지🚨

(1) 강의 정원(capacity)을 100으로 세팅

  • lecture 테이블에서 capacity를 100으로
  • enrolled(또는 enrolledCount)를 0으로 초기화

(2) 스케줄러가 admitted를 풀어줘야 함

현재 스케줄러:

@Scheduled(fixedDelay = 3000)
batchSize =1;

이대로면 admitted가 너무 천천히 풀려서 테스트가 오래 걸려.

테스트할 때만 임시로 추천:

  • fixedDelay = 1000 (1초)
  • batchSize = 20 또는 50

이유: admitted가 빨리 풀려야 “enroll 동시성”이 제대로 발생함.

(3) 서버 로그 너무 많으면 느려질 수 있음

대량 테스트 때 log.info가 너무 많으면 성능이 왜곡될 수 있어. (가능하면 줄이기)


1️⃣ JMeter 테스트 플랜 목표 구조

너가 만들 JMeter 트리는 이렇게 될 거야:

EnrollConcurrencyTest
 └─ Thread Group (Users=300, RampUp=30, Loop=1)
     ├─ HTTP Request Defaults (localhost:8080)
     ├─ 01_enqueue (POST /api/lectures/1/queue)
     │   └─ JSON Extractor: userKey = $.userKey
     ├─ While Controller (status != SUCCESS && maxLoop > 0)
     │   ├─ 02_poll_me (GET /api/lectures/1/queue/me?userKey=${userKey})
     │   │   └─ JSON Extractor: status = $.status
     │   ├─ Constant Timer (200ms~1000ms)
     │   └─ JSR223 PostProcessor (maxLoop 감소)
     ├─ If Controller (status == SUCCESS)
     │   └─ 03_enroll (POST /api/lectures/1/enroll?userKey=${userKey})
     ├─ Summary Report
     └─ View Results in Table (초반 확인용)

핵심은:

  • 유저마다 enqueue해서 userKey를 받고
  • SUCCESS 될 때까지 폴링하고
  • SUCCESS인 애들만 enroll을 때려서
  • DB가 정원을 넘지 않는지 확인하는 것!

2️⃣ JMeter에서 “하나씩 클릭해서 만드는 방법”

Step A) Thread Group 만들기

Test Plan 우클릭 → Add → Threads → Thread Group

  • Users: 300 (처음은 100으로 시작해도 OK)
  • Ramp-up: 30
  • Loop Count: 1

Step B) HTTP Request Defaults

Thread Group 우클릭 → Add → Config Element → HTTP Request Defaults

  • Protocol: http
  • Server: localhost
  • Port: 8080

Step C) 01_enqueue 만들기

Thread Group 우클릭 → Add → Sampler → HTTP Request

  • Name: 01_enqueue
  • Method: POST
  • Path: /api/lectures/1/queue

C-1) JSON Extractor로 userKey 뽑기

01_enqueue 우클릭 → Add → Post Processors → JSON Extractor

  • Names of created variables: userKey
  • JSON Path expressions: $.userKey
  • Match No.: 1
  • Default Values: NOT_FOUND

3️⃣ SUCCESS 될 때까지 폴링 반복 만들기 (While Controller)

Step D) maxLoop 변수 초기화 (한 번만)

Thread Group 우클릭 → Add → Config Element → User Defined Variables

  • Name: maxLoop
  • Value: 200
  • (폴링 최대 200번까지만, 무한루프 방지)
  • Name: status
  • Value: QUEUED
  • (초기값)

Step E) While Controller 추가

Thread Group 우클릭 → Add → Logic Controller → While Controller

While Condition에 아래를 넣어:

${__groovy(vars.get('maxLoop').toInteger() > 0 && vars.get('status') != 'SUCCESS')}

뜻:

  • maxLoop가 0보다 크고
  • status가 SUCCESS가 아닐 동안 반복

Step F) While 안에 02_poll_me 만들기

While Controller 우클릭 → Add → Sampler → HTTP Request

  • Name: 02_poll_me
  • Method: GET
  • Path: /api/lectures/1/queue/me
  • Parameters:
    • userKey = ${userKey}

F-1) poll 응답에서 status 뽑기

02_poll_me 우클릭 → Add → Post Processors → JSON Extractor

  • Names of created variables: status
  • JSON Path expressions: $.status
  • Match No : 1
  • Default Values: UNKNOWN

이제 매 폴링마다 ${status}가 QUEUED/SUCCESS/NOT_IN_QUEUE로 업데이트돼.

Step G) While 안에 Timer 추가 (폴링 간격)

While Controller 우클릭 → Add → Timer → Constant Timer

  • 200ms~1000ms 추천
    • 실전 폴링은 1초가 흔한데,
    • 테스트는 빨리 끝내려면 200~500ms도 괜찮아 (자소서엔 “테스트용으로 간격 조절”이라고 쓰면 됨)

예: 200

Step H) maxLoop 감소시키기 (무한루프 방지)

While Controller 우클릭 → Add → Post Processors → JSR223 PostProcessor

Language: groovy

Script:

def n = vars.get('maxLoop') as int
vars.put('maxLoop', String.valueOf(n - 1))

이제 폴링이 무한으로 돌지 않고 최대 200회 안에 끝나.


4️⃣ SUCCESS인 경우에만 enroll 호출하기

Step I) If Controller 추가

Thread Group 우클릭 → Add → Logic Controller → If Controller

Condition에 넣기:

${__groovy(vars.get('status') =='SUCCESS')}

Step J) 03_enroll 만들기 (If 안에)

If Controller 우클릭 → Add → Sampler → HTTP Request

  • Name: 03_enroll
  • Method: POST
  • Path: /api/lectures/1/enroll

Parameters:

  • userKey = ${userKey}

(너 컨트롤러가 @RequestParam String userKey 형태라서 이게 정확히 맞아)


5️⃣ 실행 전에 “1명으로 정상동작 확인” (이거 꼭!)

처음부터 300명 돌리면 뭐가 문제인지 못 찾아.

확인용 설정

  • Users: 1
  • Ramp-up: 1
  • maxLoop: 10
  • Timer: 200

실행 후 View Results in Table에서 흐름이:

  • enqueue 1번
  • poll 여러 번
  • SUCCESS 나오면 enroll 1번

이렇게 나오면 완벽.


6️⃣ 본 테스트(동시성) 추천 값

  • 먼저: Users 100 / Ramp-up 20
  • 성공하면: Users 300 / Ramp-up 30
  • 더 욕심내면: Users 1000 / Ramp-up 100

7️⃣ “성공” 판단 기준(가장 중요)

JMeter 결과도 중요하지만, 이 테스트의 진짜 성공은 DB 정합성이야.

✅ 테스트가 끝난 뒤 DB에서 확인:

  1. Enrollment 테이블 row 수가 정확히 100인지
  2. Lecture.enrolled가 정확히 100인지
  3. “정원 마감” 에러가 일부 발생해도 괜찮음(그건 정상)
    • 중요한 건 “초과 저장”이 없어야 함

정원 100인데 Enrollment가 101 이상이면 동시성 실패.

'프로젝트 > 스프링 부트 3 백엔드 개발자 되기 Blog + 선착순 강의 프로젝트' 카테고리의 다른 글

⏰🚨 동시성 테스트 중 500 Internal Server Error 발생 원인과 해결  (1) 2026.02.23
⏰🚨 Enroll 동시성 테스트에서 신청이 거의 발생하지 않은 문제(JMeter)  (0) 2026.02.15
⏰💡 폴링 API 부하 테스트 (500명 실험)  (0) 2026.02.15
⏰💡 JMeter 구성 요소 해석해보기  (1) 2026.02.15
⏰💡 폴링 API 부하테스트 진행 방법 (JMeter)  (0) 2026.02.15
'프로젝트/스프링 부트 3 백엔드 개발자 되기 Blog + 선착순 강의 프로젝트' 카테고리의 다른 글
  • ⏰🚨 동시성 테스트 중 500 Internal Server Error 발생 원인과 해결
  • ⏰🚨 Enroll 동시성 테스트에서 신청이 거의 발생하지 않은 문제(JMeter)
  • ⏰💡 폴링 API 부하 테스트 (500명 실험)
  • ⏰💡 JMeter 구성 요소 해석해보기
hak0622
hak0622
개발하면서 “이게 뭐지?”라는 순간마다 궁금한 점을 바탕으로 정리한 개발 블로그입니다.
  • hak0622
    궁금한 개발 이야기 Why?
    hak0622
  • 전체
    오늘
    어제
    • 분류 전체보기 (68)
      • 공부 (36)
        • 1. 자바 ORM 표준 JPA 프로그래밍 - 기본.. (35)
        • 시험 (1)
      • 프로젝트 (32)
        • 스프링 부트 3 백엔드 개발자 되기 Blog + .. (32)
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
hak0622
⏰💡 Enroll 동시성 테스트 + 폴링 API 부하테스트 진행 방법(JMeter)
상단으로

티스토리툴바