← 포트폴리오 목록
Backend Developer Portfolio

숏터디 (Shortudy)
프로젝트 상세 회고 및 아키텍처

단순 기능 구현을 넘어, 서비스 운영 기준과 트레이드오프를 고민합니다.

코드 저장소: minji0828/wantbehelp-3rd-LXP · refactor/shorts

Java 17 (Corretto) Spring Boot JPA (Hibernate) MySQL Redis AWS S3 / EC2 / RDS

프로젝트 개요 및 담당 역할

프로젝트 핵심 가치 (Why Shortudy?)

숏터디는 짧은 학습 콘텐츠를 소비하는 숏폼형 LXP(Learning Experience Platform) 지향 서비스입니다.

초기 기획 당시 추천 시스템, 마인크래프트식 뱃지 등 다양한 확장 아이디어가 논의되었으나, 가장 중요한 것은 "학습 영상의 품질 보장"이라고 판단했습니다.

이에 무분별한 콘텐츠 확장을 멈추고, 업로드 상태와 게시 가능 상태를 분리하여 콘텐츠 노출 기준을 명확히 하는 구조를 설계했습니다.

담당 영역 (Backend & Infra)

  • 업로드 파이프라인: S3 Direct Upload 설계 및 미완료 세션/고아 객체 관리
  • 상태 분리: 업로드 파이프라인 상태와 숏츠 게시 상태 분리
  • 조회 성능: Redis Write-back 기반 집계 및 projection DTO 조회 경로 구성
  • 데이터 무결성: FK 충돌 방지를 위한 삭제 순서 통제 (Hard Delete)
  • BackOffice: 업로드 수, 전환율 등 비즈니스 지표 API 구현
  • 배포 인프라: Docker Compose 구성 및 단일 EC2 → RDS 분리 개선

* Frontend(Next.js), 디자인, 보안 전반은 타 팀원 소관으로 본 기여도에서 제외함.

01. 핵심 아키텍처 & 설계 판단

기술의 맹목적 도입이 아닌, 현재 상황에 맞는 trade-off 기반의 설계

S3 Direct Upload 파이프라인 설계 판단

왜 Presigned URL인가?

사용자가 서버를 거치지 않고 S3에 직접 업로드하는 구조를 채택했습니다.

  • 대안 비교: Multipart Upload, STS(임시 자격증명), Presigned POST 등을 검토했습니다.
  • 선택 근거: 숏폼 특성상 초대용량 파일이 아니므로 Multipart 장점이 크지 않았고, STS는 초기 권한 설계/클라이언트 공수가 과하다고 판단했습니다.
  • 결과: 백엔드 부하를 최소화하면서도 구현 속도와 구조 단순성을 확보했습니다.

업로드 세션 관리 (고아 데이터 정리)

Direct Upload의 한계 중 하나인 '이탈 시 고아 데이터 누적(스토리지 비용 증가)'을 방지하기 위해, 업로드 세션을 발급/관리하고 실패 재시도 시 이전 세션의 찌꺼기를 정리하는 로직과 스케줄러를 구축했습니다.

* 한계점: 단, 현재 구조는 클라이언트의 완료 요청에 의존하므로 '실제 S3 객체 존재 여부'를 백엔드에서 동기적으로 100% 보장하지 못하는 아쉬움이 존재합니다.

AWS Architecture Diagram with S3 and EC2

데이터 성격에 따른 상태 관리 및 집계 구조

업로드 / 게시 상태 분리

AI 검수 기능 도입으로, 파일 업로드 완료가 곧 '공개'를 의미해선 안 됐습니다.

설계: 파일 업로드 완료 여부와 숏츠의 비즈니스 상태를 분리하여, 업로드 파이프라인과 게시/조회 정책이 섞이지 않도록 구성했습니다.

조회수 Redis Write-back

조회수는 강한 정합성보다 쓰기 경합 해소가 중요한 데이터입니다.

설계: 매 요청마다 DB를 Update하지 않고 Redis INCR로 메모리에 누적 후 주기적으로 MySQL에 지연 반영(Write-back)하여 부하를 분산했습니다.

읽기 경로 (N+1 완화)

키워드와 실시간 조회수를 조합하기 위해 복잡한 엔티티 그래프 대신, projection DTO 기반 기본 데이터 조회 + 키워드 배치(In 절) 조회 + Redis 병합으로 응답 조립 책임을 분리했습니다.

02. 기술적 문제 해결 (Troubleshooting)

서비스 운영 중 발생할 수 있는 데이터 정합성과 인프라 문제 개선

트러블슈팅 AS-IS / TO-BE

영역 AS-IS (문제 상황) TO-BE (해결 및 설계 판단)
데이터 무결성
(삭제 시 FK 충돌)
회원 탈퇴나 숏츠 삭제 시, 연관된 자식 Row(좋아요, 댓글 등)가 남아있어 외래키 제약조건 위배로 부모 삭제(Soft Delete 포함)가 실패함. 부모 삭제 전, 트랜잭션 내에서 FK를 직접 참조하는 자식 데이터를 먼저 Hard Delete 하도록 삭제 순서를 서비스 레벨에서 명확히 제어하여 무결성을 보장함.
배포 및 인프라
(SPOF 한계)
초기 단일 EC2 인스턴스에 App, Redis, MySQL을 모두 올려 장애 발생 시 DB 데이터까지 통째로 유실되는 치명적 문제를 겪음. 데이터 계층을 Amazon RDS로 완전 분리하고, EC2에는 Docker Compose 기반으로 클라이언트, Redis, 백오피스 API를 나누어 배치하는 구조로 재설계.
비즈니스 지표 API
(BackOffice)
업로드 수, 전환율 등 비즈니스 지표를 클라이언트에서 개별 계산하면 시간대나 산출 기준 차이로 수치 기준이 흔들릴 위험 존재. BackOffice API 계층에서 KST 기준, 분모/분자 산출 기준, 입력 기간 처리를 정리하여 서버가 지표 계산 기준을 제공하도록 구현.

아쉬운 점 및 향후 아키텍처 계획 (Future Plans)

영역 현재의 한계 (Limitations) 추후 아키텍처 계획 (To-Be Architecture)
객체 존재 검증
(S3 무결성)
Direct Upload 후 클라이언트의 API 호출만으로 게시를 처리하여, 실제 S3에 파일이 정상적으로 존재하는지 백엔드에서 교차 검증하지 못함. S3 Event Notification을 활용하여, 파일 업로드 완료 이벤트를 백엔드가 수신한 뒤에만 최종 '게시 가능 상태'로 전환하는 비동기 검증 파이프라인 구축.
썸네일 및
미디어 후처리
서버(FFmpeg)에서 동기적으로 미디어를 처리하면 Direct Upload의 부하 분산 이점이 사라지며, 처리 지연 시 타임아웃 발생 우려가 있음. 트래픽 증가에 대비하여 `S3 이벤트 → SQS(완충) → AWS Lambda` 형태의 이벤트 기반 아키텍처(EDA)로 미디어 처리를 분리하고 재시도 큐를 구성.
조회수 어뷰징
(Unique View)
무분별한 조회수 중복을 막기 위해 비회원 식별 시 IP와 User-Agent 해싱에 의존. 이는 NAT 환경 등에서 충돌 가능성이 높음. IP 의존을 줄이고, 애플리케이션 조회수는 서버에서 발급하는 익명 UUID 쿠키 기반 식별 방식으로 고도화.

03. 회고 및 성장

팀 프로젝트에서의 협업 기준, AI 코드 검토, 그리고 trade-off 기록

일하는 방식의 재정립

  • 팀 프로젝트 협업 기준: 컨벤션 부재와 업무 쏠림 문제를 겪으며, 개발 공수 산정 및 회의 아젠다를 명확히 하는 협업 기준 마련의 중요성을 체감했습니다.
  • 맹목적 AI 코드 병합 거부: 생산성에 쫓겨 팀원이 가져온 '이해하지 못한 AI 생성 코드'를 병합하지 않았습니다. 설명 불가능한 코드는 장기적으로 치명적인 부채가 됨을 깨닫고, 퀄리티를 타협하더라도 통제 가능한 코드 중심으로 진행했습니다.
  • Trade-off 기록: 운영 자동화/모니터링의 부재(Grafana, CI/CD 등)라는 한계를 인정하고, 대신 왜 이 기술을 택했고 무엇을 감수했는지를 정리하며 엔지니어링 사고방식을 훈련했습니다.
Developers discussing code on a laptop

소통 방식과 결과물의 완성도

발표와 문서화를 통한 시스템 이해

단순한 산출물 제출이 아닌, 팀 프로젝트 전체의 구조를 설명하기 위해 PPT를 직접 제작하고 여러 발표 방식을 실험했습니다.

문서를 정리하고 발표를 준비하는 과정이 선순환되어, 단편적인 내 파트를 넘어 프로젝트 전반의 아키텍처 조감도를 깊이 이해하는 계기가 되었습니다.

"100개의 불안정함 보다, 50의 완성도"

시간과 체력을 갈아 넣어 무리하게 확장된 기능을 욱여넣는 것보다, 정해진 기준 안에서 명확히 설계된 핵심 기능의 완성도와 안정성이 서비스에 훨씬 더 중요하다는 것을 체감했습니다.

양으로 증명하기보다, 제대로 된 엔지니어링 기준(Trade-off 고려, 삭제 무결성, 조회수 부하 분산)을 세우는 데 집중했습니다.

감사합니다.

기능 구현에 그치지 않고,
상태 분리, 지연 반영, 삭제 순서 제어, 운영 기준 확정처럼
실제 서비스가 버틸 수 있는 구조를 고민하는 백엔드 개발자입니다.

Shortudy Backend Engineer Portfolio