Feat/170 : 로컬 k6 기반 부하 테스트 환경 구성 및 테스트 스크립트 작성 Ai 피드백 처리 멀티 워커 구조 도입#171
Feat/170 : 로컬 k6 기반 부하 테스트 환경 구성 및 테스트 스크립트 작성 Ai 피드백 처리 멀티 워커 구조 도입#171HeeMang-Lee merged 2 commits intodevfrom
Conversation
Walkthrough이 변경 사항은 AI 피드백 처리의 동시성 향상, 테스트 및 부하 테스트를 위한 환경 지원, 그리고 도커 기반 통합 환경 및 부하 테스트 스크립트 도입을 포함합니다. 또한, AI 피드백 스트림 처리 로직에 테스트용 하드코딩 응답을 적용하고, 테스트 데이터 자동 초기화 기능이 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant k6(VU)
participant cs25-service
participant AiFeedbackStreamProcessor
User->>k6(VU): 부하 테스트 시작
k6(VU)->>cs25-service: GET /feedback/stream/{answerId} (SSE)
cs25-service->>AiFeedbackStreamProcessor: stream(answerId, emitter)
AiFeedbackStreamProcessor->>AiFeedbackStreamProcessor: (300ms 대기, 하드코딩 응답 생성)
AiFeedbackStreamProcessor-->>cs25-service: 응답 전송 (SSE)
cs25-service-->>k6(VU): SSE 응답 전송
k6(VU)->>User: 결과 확인
Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
🔇 Additional comments (2)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
docker-compose.yml (1)
134-134: YAML 파일 끝에 개행 문자를 추가하세요.YAMLlint에서 파일 끝에 개행 문자가 없다고 경고하고 있습니다.
파일 끝에 빈 줄을 추가하세요:
networks: monitoring: +cs25-service/src/main/java/com/example/cs25service/domain/ai/service/AiFeedbackQueueService.java (2)
24-24: 워커 수를 설정 가능하게 만드는 것을 고려해보세요.고정된 16개의 워커는 현재 부하 테스트에는 적합하지만, 운영 환경에서는 다른 값이 더 적절할 수 있습니다.
-private final int WORKER_COUNT = 16; +@Value("${ai.feedback.worker.count:16}") +private int workerCount;application.yml에서 설정할 수 있도록 하면 더 유연한 구성이 가능합니다.
26-29: 스레드 이름 지정 방식을 개선해보세요.현재
r.hashCode()를 사용한 스레드 이름은 가독성이 떨어집니다.-private final ExecutorService executor = Executors.newFixedThreadPool( - WORKER_COUNT, - r -> new Thread(r, "ai-feedback-worker-" + r.hashCode()) -); +private final ExecutorService executor = Executors.newFixedThreadPool( + WORKER_COUNT, + new ThreadFactoryBuilder() + .setNameFormat("ai-feedback-worker-%d") + .setDaemon(true) + .build() +);또는 AtomicInteger를 사용하여 순차적인 번호를 부여할 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
.DS_Storeis excluded by!**/.DS_Store
📒 Files selected for processing (6)
cs25-service/src/main/java/com/example/cs25service/domain/ai/client/FallbackAiChatClient.java(1 hunks)cs25-service/src/main/java/com/example/cs25service/domain/ai/service/AiFeedbackQueueService.java(1 hunks)cs25-service/src/main/java/com/example/cs25service/domain/ai/service/AiFeedbackStreamProcessor.java(1 hunks)cs25-service/src/main/java/com/example/cs25service/domain/ai/test/TestDataInitializer.java(1 hunks)docker-compose.yml(1 hunks)k6/scripts/sse-test.js(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
docker-compose.yml
[error] 134-134: no new line character at the end of file
(new-line-at-end-of-file)
🔇 Additional comments (7)
k6/scripts/sse-test.js (1)
1-23: 로드 테스트 스크립트가 잘 구성되었습니다.500명의 동시 사용자로 60초간 SSE 엔드포인트를 테스트하는 설정이 적절합니다. SSE 헤더와 타임아웃 설정도 올바르게 구성되어 있고, 1-1000 범위의 랜덤 answer ID 생성이 테스트 데이터와 일치합니다.
cs25-service/src/main/java/com/example/cs25service/domain/ai/service/AiFeedbackStreamProcessor.java (2)
33-33: 사용자 답변 조회 로직 변경이 적절합니다.
findWithQuizAndUserById에서findById로 변경하여 불필요한 조인을 제거했습니다. 이후 코드에서answer.getQuiz()와answer.getUser()를 통해 필요한 데이터에 접근하므로 로직상 문제없습니다.
42-49: 테스트용 AI 응답 모킹이 잘 구현되었습니다.실제 AI 호출을 300ms 대기와 하드코딩된 응답으로 대체하여 로드 테스트 중 API 비용을 절약하면서도 실제 응답 시간을 시뮬레이션합니다.
FallbackAiChatClient의 모킹 로직과 일관성을 유지하고 있습니다.docker-compose.yml (1)
108-125: k6 로드 테스트 설정이 잘 구성되었습니다.k6 서비스가 Prometheus와 통합되어 메트릭을 수집하고,
host.docker.internal을 통해 호스트의 애플리케이션에 접근할 수 있도록 설정되어 있습니다. 네이티브 히스토그램 기능도 활성화되어 있어 상세한 성능 메트릭 수집이 가능합니다.cs25-service/src/main/java/com/example/cs25service/domain/ai/service/AiFeedbackQueueService.java (3)
23-23: 큐 용량 증가가 적절합니다.부하 테스트 요구사항에 맞춰 큐 용량을 100에서 500으로 증가시킨 것은 적절한 변경입니다.
35-37: 멀티 워커 초기화 로직이 올바릅니다.여러 워커를 동시에 시작하는 로직이 정확하게 구현되었습니다.
BlockingQueue는 스레드 안전하므로 여러 워커가 동시에 큐를 처리하는데 문제없습니다.
52-63: 동시성 처리 시 주의사항을 확인해보세요.현재 구현은 올바르지만,
AiFeedbackStreamProcessor.stream()메서드가 멀티 스레드 환경에서 안전한지 확인이 필요합니다.다음 스크립트로 스트림 프로세서의 스레드 안전성을 확인해보세요:
#!/bin/bash # Description: AiFeedbackStreamProcessor의 thread-safety 관련 구현을 확인합니다. # AiFeedbackStreamProcessor 클래스의 stream 메서드 구현 확인 ast-grep --pattern 'class AiFeedbackStreamProcessor { $$$ public $_ stream($_, $_) { $$$ } $$$ }' # 공유 상태나 동시성 이슈 가능성 확인 rg -A 10 -B 5 "class AiFeedbackStreamProcessor"
🔎 작업 내용
MOCK_AI=true환경변수 도입 → 테스트 시 실제 API 호출 차단🛠️ 변경 사항
✅ 피드백 처리 구조 개선
AiFeedbackQueueServiceBlockingQueue용량: 100 → 500 증가ExecutorService→FixedThreadPool전환AiFeedbackStreamProcessorThread.sleep(300)으로 응답 간 지연 시뮬레이션✅ 테스트 데이터 및 환경
TestDataInitializer@Profile("loadtest")활성 시,UserQuizAnswer1,000건 bulk insertFallbackAiChatClientSystem.getenv("MOCK_AI") == "true"시 OpenAI 호출 생략하고 테스트용 응답 반환✅ 부하 테스트 스크립트
k6/scripts/sse-test.js/quizzes/{answerId}/feedbackSSE 요청 부하 발생🧩 트러블 슈팅
MOCK_AI=true설정 시 하드코딩 응답 반환📌 참고 사항
closed #170
Summary by CodeRabbit
신규 기능
버그 수정
테스트
기타