Skip to content

과팅 연결 부하테스트 - #305

Open
rdyjun wants to merge 4 commits into
mainfrom
test/blinddate-performance-test
Open

과팅 연결 부하테스트#305
rdyjun wants to merge 4 commits into
mainfrom
test/blinddate-performance-test

Conversation

@rdyjun

@rdyjun rdyjun commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

Closes #이슈번호

🎯 배경

  • 과팅 이벤트 개설 시 사용자가 경험할 수 있는 지연 확인

🔍 주요 내용

  • 1,000명의 사용자를 3초간 지속적으로 입장시켰을 때 최대 10초 이내 지연 평균 3~4초 소요 확인
    • EC2의 1기가 메모리, 1코어 환경
  • blinddate의 SockJS 설정 제거
  • logs 디렉터리 및 generated 디렉터리 gitignore 등록

⌛️ 리뷰 소요 시간

5분

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 블라인드 데이트 기능을 위한 새로운 WebSocket 엔드포인트 추가
  • Tests

    • 로드 테스트 인프라 및 자동화된 테스트 스크립트 구성 추가
  • Chores

    • 빌드 및 배포 설정 업데이트
    • 무시 규칙 및 Docker 컨테이너 설정 개선

@rdyjun rdyjun added this to the 과팅 milestone Feb 16, 2026
@rdyjun rdyjun self-assigned this Feb 16, 2026
@rdyjun rdyjun added the test label Feb 16, 2026
@coderabbitai

coderabbitai Bot commented Feb 16, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

WebSocket 설정에 origins 기반의 새로운 엔드포인트가 추가되었고, K6 로드 테스트 환경(Dockerfile, docker-compose, 테스트 스크립트)이 추가되었습니다. .gitignore, build.gradle, 애플리케이션 설정 파일에 소소한 변경이 이루어졌습니다.

Changes

Cohort / File(s) Summary
빌드 및 설정 관리
.gitignore, build.gradle, src/main/resources/application-local.yml
.gitignore에 logs/ 및 **/src/main/generated/ 패턴 추가, build.gradle의 의존성 블록에 설명 주석 추가, appcheck.ignore-path를 /ws/\*\에서 /\\*로 확대
WebSocket 설정
src/main/java/com/dongsoop/dongsoop/common/config/WebSocketConfig.java
@Value를 통한 origins 의존성 주입 추가, 새로운 /ws/blinddate STOMP 엔드포인트 구성 및 origins 배열 기반의 접근 제어 적용
K6 로드 테스트 환경
src/test/k6/blinddate_load_test/Dockerfile, src/test/k6/blinddate_load_test/docker-compose.yml, src/test/k6/blinddate_load_test/script.js
멀티스테이지 Dockerfile로 Spring Boot 애플리케이션 빌드 및 실행 환경 구성, docker-compose로 blinddate-test 서비스와 K6 로드 제너레이터 조율, K6 스크립트로 1000/s 상수 도착률의 WebSocket 기반 blind date 흐름 시뮬레이션

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 새로운 길 따라 쏜살, 로드 테스트의 날개 달아
웹소켓 엔드포인트 두둥실 떠오르고,
도커 컨테이너는 춤을 춘다네
K6의 천 마리 토끼들이 깡충깡충,
origins 허락 얻어 안전하게 대화 나눈다! 🚀

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목 '과팅 연결 부하테스트'는 변경 사항의 핵심을 명확하게 요약하고 있습니다. K6을 사용한 blinddate 소켓 연결 부하 테스트 추가라는 주요 변경 내용을 잘 나타냅니다.
Description check ✅ Passed PR 설명이 템플릿 구조를 따르고 있으며, 배경, 주요 내용, 리뷰 소요 시간이 모두 포함되어 있습니다. 테스트 결과와 구체적인 변경 사항이 명확하게 기술되어 있습니다.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test/blinddate-performance-test

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@build.gradle`:
- Around line 73-75: The build currently declares H2 as developmentOnly
('developmentOnly' dependency for com.h2database:h2) while the comment says it
should be runtimeOnly for k6 tests and there's no handling of the -PincludeH2
flag; update build.gradle to ensure H2 is available for containerized k6 tests
by either changing the H2 dependency scope from developmentOnly to runtimeOnly
for com.h2database:h2, or add conditional logic that checks
project.hasProperty('includeH2') (or the -PincludeH2 flag) and registers the H2
dependency as runtimeOnly only when that flag is provided so k6 test containers
get H2 on the classpath.
🧹 Nitpick comments (7)
src/main/resources/application-local.yml (1)

199-200: 로컬 프로필에서 앱체크 전체 경로 무시 — 의도 확인 필요

ignore-path/**로 설정하면 로컬 환경에서 모든 경로의 앱체크가 비활성화됩니다. 부하 테스트를 위한 변경이라면 이해되지만, 이 설정이 main 브랜치에 머지되면 로컬 개발 시 앱체크 관련 버그를 놓칠 수 있습니다. 테스트 완료 후 원래 값(/ws/** 등)으로 복원하는 것을 권장합니다.

src/main/java/com/dongsoop/dongsoop/common/config/WebSocketConfig.java (1)

36-46: /ws/chat/ws/blinddate 엔드포인트의 보안 설정 불일치

/ws/chatsetAllowedOriginPatterns("*")로 모든 오리진을 허용하지만, /ws/blinddate는 설정 파일의 origins로 제한합니다. 의도된 차이라면 문제없지만, /ws/chat에도 동일한 오리진 제한을 적용하는 것이 보안상 바람직합니다.

src/test/k6/blinddate_load_test/Dockerfile (2)

32-32: COPY 경로가 혼란스러움 — 절대 경로 사용 권장

../../build/build/libs/*.jar 경로는 현재 WORKDIR(/app) 기준으로 /build/build/libs/*.jar로 해석되어 동작하지만, 상대 경로가 직관적이지 않습니다.

♻️ 절대 경로로 변경
-COPY --from=builder ../../build/build/libs/*.jar app.jar
+COPY --from=builder /build/build/libs/*.jar app.jar

27-42: 컨테이너가 root 사용자로 실행됨

Trivy 정적 분석에서도 지적된 것처럼, 컨테이너가 root로 실행됩니다. 테스트 전용 Dockerfile이지만, 비root 사용자로 실행하는 것이 좋은 습관입니다.

🛡️ 비root 사용자 추가
 COPY --from=builder /build/build/libs/*.jar app.jar

 RUN apt-get update && \
     apt-get install -y --no-install-recommends curl && \
     rm -rf /var/lib/apt/lists/*

+RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
+USER appuser
+
 ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
src/test/k6/blinddate_load_test/script.js (2)

10-11: 하드코딩된 시크릿 키 (Gitleaks 경고)

SECRET_KEY가 스크립트에 하드코딩되어 있습니다. application-local.yml에 있는 로컬 개발용 키와 동일하지만, 테스트 스크립트에도 중복 관리되면 키 변경 시 동기화가 누락될 수 있습니다. 환경 변수(__ENV.SECRET_KEY)로 주입하는 방식을 고려해 주세요.

♻️ 환경 변수로 주입
-const SECRET_KEY = 'VGhpc0lzQVZlcnlMb25nU2VjcmV0S2V5Rm9yRG9uZ3Nvb3BMb2NhbERldmVsb3BtZW50VGVzdGluZ1B1cnBvc2VPbmx5MTIzNDU2';
+const SECRET_KEY = __ENV.SECRET_KEY || 'VGhpc0lzQVZlcnlMb25nU2VjcmV0S2V5Rm9yRG9uZ3Nvb3BMb2NhbERldmVsb3BtZW50VGVzdGluZ1B1cnBvc2VPbmx5MTIzNDU2';

그런 다음 docker-compose.yml의 k6 서비스에서 환경 변수로 전달:

environment:
  - SECRET_KEY=VGhpc0lz...

117-151: STOMP 메시지 핸들러에서 CONNECTEDMESSAGE 분기 로직 확인

Line 119에서 msg.startsWith('CONNECTED')를 체크한 뒤 구독을 보내고, Line 126에서 !msg.startsWith('MESSAGE')이면 리턴합니다. CONNECTED 메시지를 받았을 때 구독 후 바로 리턴하지 않기 때문에, CONNECTED로 시작하는 메시지가 Line 126의 체크도 통과하여 불필요하게 body 파싱을 시도합니다. 기능상 문제는 없지만(catch에서 무시), else if 또는 early return으로 명확히 분리하는 것이 좋습니다.

♻️ early return 추가
         socket.on('message', function (msg) {
             if (msg.startsWith('CONNECTED')) {
                 socket.send(`SUBSCRIBE\nid:sub-0\ndestination:/user/queue/blinddate/join\n\n\0`);
-
+                return;
             }
 
             if (!msg.startsWith('MESSAGE')) {
src/test/k6/blinddate_load_test/docker-compose.yml (1)

1-1: version 키는 Docker Compose v2에서 더 이상 사용되지 않음

최신 Docker Compose에서는 version 필드가 무시되며 경고가 출력됩니다. 제거해도 무방합니다.

Comment thread build.gradle
Comment on lines +73 to 75

// k6 테스트 시 runtimeOnly로
developmentOnly 'com.h2database:h2'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for includeH2 property and conditional logic in build.gradle
rg -n 'includeH2|developmentOnly.*h2|h2.*developmentOnly' build.gradle

# Also search for any gradle properties or initialization scripts
fd -name 'build.gradle*' -o -name 'gradle.properties' -o -name 'settings.gradle*' | head -20

Repository: dongsooop/backend

Length of output: 351


🏁 Script executed:

#!/bin/bash
# Search for includeH2 and other H2 configurations in build.gradle
rg -i 'includeh2|h2|runtimeonly' build.gradle

# Check for gradle.properties
cat gradle.properties 2>/dev/null || echo "No gradle.properties found"

# Count lines in build.gradle to determine size
wc -l build.gradle

Repository: dongsooop/backend

Length of output: 361


🏁 Script executed:

#!/bin/bash
# Read the entire build.gradle
cat -n build.gradle

# Also search for any other gradle files
find . -maxdepth 2 -name "*.gradle" -o -name "*.gradle.kts" 2>/dev/null | head -10

Repository: dongsooop/backend

Length of output: 3521


🏁 Script executed:

#!/bin/bash
# Read settings.gradle
cat settings.gradle

# Also search for any other gradle configuration
find . -maxdepth 2 -type f \( -name "*.gradle" -o -name "*.gradle.kts" -o -name "gradle.properties" \) 2>/dev/null

Repository: dongsooop/backend

Length of output: 123


H2 의존성 스코프와 주석 불일치

주석에는 "k6 테스트 시 runtimeOnly로"라고 되어 있지만, 실제 H2 의존성은 developmentOnly로 선언되어 있습니다. Spring Boot의 developmentOnly 스코프는 로컬 개발 환경에서만 포함되며, Dockerfile 빌드 시에는 제외됩니다. 따라서 k6 테스트 컨테이너에서 H2가 클래스패스에 없어 local 프로필(H2 datasource 사용) 실행이 실패할 수 있습니다.

현재 build.gradle에 -PincludeH2 플래그를 처리하는 조건부 로직이 없으므로, k6 테스트가 컨테이너 환경에서 실행될 경우 의존성 누락으로 인한 오류가 발생할 수 있습니다. H2 의존성 스코프를 runtimeOnly로 변경하거나, 조건부 로직을 추가하여 명시적으로 처리해야 합니다.

🤖 Prompt for AI Agents
In `@build.gradle` around lines 73 - 75, The build currently declares H2 as
developmentOnly ('developmentOnly' dependency for com.h2database:h2) while the
comment says it should be runtimeOnly for k6 tests and there's no handling of
the -PincludeH2 flag; update build.gradle to ensure H2 is available for
containerized k6 tests by either changing the H2 dependency scope from
developmentOnly to runtimeOnly for com.h2database:h2, or add conditional logic
that checks project.hasProperty('includeH2') (or the -PincludeH2 flag) and
registers the H2 dependency as runtimeOnly only when that flag is provided so k6
test containers get H2 on the classpath.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants