개요
JD 분석, 질문 생성, 피드백 스트리밍이 한 흐름에 몰리면 응답 지연과 리소스 경합이 커집니다. 이 프로젝트에서는 면접 코칭 흐름을 Gateway, 면접, AI, 통계 서비스로 분리하고 LangChain4j + ChromaDB RAG, SSE 스트리밍, Redis 캐시를 붙여 실시간 피드백을 구성했습니다. 특히 SSE 스레드 분리, 통계 업데이트 동시성 제어, 임베딩 배치 처리처럼 운영 중 병목이 생기기 쉬운 백엔드 문제를 직접 해결했습니다.
서비스 구성 (5개 독립 서비스)
- ›API Gateway(8080): Spring Cloud Gateway, JWT 검증, 라우팅, Rate Limit
- ›User Service(8081): 회원가입, 로그인(JWT), 프로필 관리
- ›Interview Service(8082): JD 분석, 질문 생성, 모의 면접 세션 관리
- ›AI Service(8083): LangChain4j + ChromaDB RAG, 답변 평가, SSE 피드백 스트리밍
- ›Statistics Service(8084): 사용자별 면접 통계, 일별 활동 집계
AI / RAG 파이프라인
- ›LangChain4j로 JD 텍스트 → 직무 키워드 추출 → 맞춤 면접 질문 생성
- ›ChromaDB 벡터 DB에 기술 면접 Q&A 임베딩 저장 (768차원)
- ›사용자 답변 → 임베딩 변환 → ChromaDB 유사도 검색 → 컨텍스트 주입 → LLM 평가
- ›SSE(Server-Sent Events)로 AI 피드백을 토큰 단위 실시간 스트리밍
성능 최적화
- ›N+1 문제: 면접 세션 목록 조회 시 @EntityGraph로 1쿼리 최적화
- ›Race Condition: 통계 업데이트 시 비관적 락으로 동시성 제어
- ›SSE Starvation: 피드백 스트리밍 시 별도 스레드풀(20개) 분리로 블로킹 방지
- ›임베딩 배치: 개별 API 호출 → 배치 처리로 JD 분석 시간 40% 단축
- ›Redis 캐싱: 질문 목록·통계 조회 TTL 캐싱으로 응답 60% 개선
인프라 & DevOps
- ›Docker Compose: 5개 서비스 + PostgreSQL + Redis + ChromaDB 일괄 기동
- ›Kubernetes: Helm 차트, AI Service HPA(CPU 80% 기준 1-3 replicas)
- ›Prometheus + Grafana: RPS, 레이턴시, JVM 메모리, AI 응답 시간 모니터링
- ›GitHub Actions: CI(빌드+테스트) + CD(ghcr.io 이미지 푸시)
아키텍처
전체 아키텍처▼
ERD
전체 ERD▼
시퀀스 다이어그램
JD 분석 & 질문 생성▼
모의 면접 세션▼
AI 피드백 (SSE 스트리밍)▼
문제 원인
- 01면접 세션 목록 조회 시 세션별 QnA 개수를 가져오기 위해 N+1 쿼리가 발생해 응답이 느렸습니다.
- 02여러 사용자가 동시에 면접을 완료하면 통계 테이블 업데이트 시 Race Condition으로 데이터 정합성이 깨졌습니다.
- 03SSE 피드백 스트리밍이 서블릿 스레드를 점유해, 동시 요청이 많아지면 다른 API 응답이 지연되었습니다.
- 04JD 분석 시 키워드마다 개별 임베딩 API를 호출해 전체 처리 시간이 길었습니다.
해결 과정
- 01@EntityGraph로 세션-QnA 연관관계를 즉시 로딩하고, @Query로 COUNT 서브쿼리를 사용해 1회 쿼리로 최적화했습니다.
- 02통계 업데이트 시 비관적 락(@Lock(PESSIMISTIC_WRITE))을 적용하고, @Retryable(maxAttempts=3)로 락 획득 실패 시 재시도를 구현했습니다.
- 03SSE 전용 스레드풀(core 10, max 20)을 분리하고, AsyncTaskExecutor로 피드백 스트리밍을 비동기 처리해 서블릿 스레드 블로킹을 방지했습니다.
- 04LangChain4j의 배치 임베딩 API를 활용해 키워드를 한 번에 벡터화하고, Redis에 임베딩 결과를 24시간 TTL로 캐싱했습니다.
결과
- 01면접 세션 목록 API: N+1(세션 수+1) → 1회 쿼리, 응답 시간 65% 개선.
- 02동시 통계 업데이트: Race Condition 해소, 100명 동시 완료 테스트에서 데이터 정합성 100% 유지.
- 03SSE 스레드풀 분리: 동시 50명 피드백 스트리밍 중에도 일반 API p95 응답 시간 50ms 이내 유지.
- 04임베딩 배치 + 캐싱: JD 분석 시간 40% 단축, Redis 캐시 적용으로 반복 조회 60% 개선.