← 문제 해결 기록

2인 팀 · 이전 프로젝트 · 2025.04 - 2025.06 (개인 개선 2026.02)

Aidiary

오래 걸리는 AI 작업의 수명과 웹 요청의 수명을 분리했습니다.

개요

기간
2025.04 - 2025.06 (개인 개선 2026.02)
참여 형태
2인 팀 · 이전 프로젝트
담당
백엔드·인프라 개선
목적
산모가 일기를 쓰며 감정 피드백을 받고, 부모 사진으로 만든 아기 캐릭터를 볼 수 있게 하는 것
대상
임신 중인 산모
사용 기술
Spring Boot · RabbitMQ · AWS
2인 캡스톤 프로젝트 이후 개인적으로 백엔드와 인프라를 개선했습니다.

구현 기능과 기술 선택

  • 일기 작성과 AI 감정 분석 피드백
  • 부모 사진 기반 아기 캐릭터 합성
  • 임신 주차·건강 정보를 반영한 개인화 정보 제공
  • Spring Security·JWT 인증과 일기 CRUD API, 약 30초 걸리는 AI 합성 작업을 RabbitMQ와 Python Worker로 분리 (수동 ACK, 멱등성 가드, 실패 메시지 경로)
  • Docker Compose로 5개 서비스 구성, AWS EC2·S3·CloudFront 배포와 GitHub Actions CI/CD
Spring Boot + Flask 이중 서버
MediaPipe 등 Python 전용 라이브러리가 필요해 AI 합성을 별도 서버로 분리했습니다.
RabbitMQ
@Async와 JVM 내부 상태 저장은 부하와 재배포에서 작업 유실과 인스턴스 간 상태 공유의 한계가 있었습니다. 작업 수명을 웹 서버와 분리하려고 메시지 큐를 선택했습니다.

트러블슈팅

JVM 안의 비동기 작업을 메시지 큐로 옮기기

문제 상황

일기로 아기 캐릭터를 만드는 AI 합성은 한 건에 약 30초가 걸렸고, 그동안 웹 서버 자원을 붙잡았습니다.

해결 과정

먼저 @Async와 JVM 내부 상태 저장으로 요청을 빨리 반환해 봤지만, 부하가 몰리면 자원 관리가 어렵고 재배포하면 진행 중인 작업이 사라졌으며 인스턴스끼리 상태를 공유할 수 없었습니다. 작업의 수명을 웹 서버와 분리하려고 RabbitMQ를 택했습니다. 운영할 구성 요소가 하나 늘어나는 대신, WAS는 접수 응답만 반환하고 Python Worker가 수동 ACK로 작업을 처리합니다. 재전달에 대비해 멱등성 가드와 실패 메시지 경로를 뒀습니다.

결과

외부 AI 서버를 내린 상태에서도 코어 API가 응답하는 것을 확인했습니다.

선택 이유: 웹 요청을 빨리 반환하는 것에 더해, WAS 재배포와 작업 상태의 수명을 분리할 필요가 있었습니다.

남은 한계: Worker 상태와 큐 적체의 운영 관측, 완료 알림 방식은 별도로 보강해야 합니다.

결과와 성과

  • 웹 요청은 접수 응답만 반환하도록 바꿔 AI 서버 중단 시에도 코어 API 응답 유지
  • WAS 재배포와 AI 작업 상태의 수명 분리 (JVM 내부 비동기의 작업 유실·상태 공유 한계에 대응)

회고

배운 점
요청을 빨리 반환하는 것과 작업을 끝내는 것이 다른 문제라는 점을 배웠습니다. 큐에 접수된 수를 완료 처리량으로 쓰지 않게 됐습니다.
아쉬운 점
Worker의 완료 처리량·큐 적체·완료 대기시간을 지표로 남기지 못했습니다.
보완 계획
Worker 상태와 큐 적체의 운영 관측, 완료 알림 방식을 보강하는 것이 남은 과제입니다.