PROJECT CASE STUDY / 백엔드 설계 및 개발
NEMO
네컷모아QR 기반 네컷사진 관리 서비스. 사진을 저장하고 조회하는 과정의 성능과 정합성을 개선했습니다.
담당한 일
- 백엔드 도메인과 API 설계
- 사진 조회의 N+1 최적화
- 사진 저장 한도 동시성 제어
- 외부 API 호출 최적화
- 모니터링과 성능 테스트
서비스의 큰 구조
다이어그램을 불러오는 중입니다. flowchart TD C[Client] --> A[Spring Boot API] A --> J[JPA] J --> P[(PostgreSQL)] A --> S[(AWS S3)] A --> E[외부 QR API]
다이어그램 텍스트 원본
flowchart TD C[Client] --> A[Spring Boot API] A --> J[JPA] J --> P[(PostgreSQL)] A --> S[(AWS S3)] A --> E[외부 QR API]
해결한 기술적 문제
ENGINEERING NOTE / 01
조회는 한 번인데, SQL은 202번
원인
사진 조회 중 연관 데이터에 접근하면서 반복 SQL이 발생하는 N+1 문제를 다뤘습니다.
선택한 해결 방법
조회 목적에 맞는 연관 데이터 로딩 전략을 적용하고 SQL 횟수와 응답시간을 비교했습니다. 정확한 매핑과 변경 코드는 원본 저장소 연결 후 보완합니다.
적용 결과
SQL 202회 → 4회, 평균 98.91ms → 10.91ms, p95 114.20ms → 15.19ms.
트레이드오프
Fetch Join은 컬렉션 페이징과 중복 행 증가를 주의해야 합니다. 쿼리 수만 줄이는 것과 전체 비용을 줄이는 것은 다릅니다.
배운 점
로그에서 원인을 찾고, 같은 조건에서 전후를 측정해야 최적화의 효과를 판단할 수 있습니다.
ENGINEERING NOTE / 02
19장에서 동시에 8장을 저장한다면
원인
각 요청이 같은 기존 사진 수를 읽으면 20장 제한 검사와 저장 사이에 경쟁이 생깁니다.
선택한 해결 방법
PostgreSQL 행 잠금으로 동일 사용자의 한도 검사와 사진 저장을 직렬화했습니다. 잠글 대상은 항상 존재하는 사용자 또는 앨범 행이어야 합니다.
적용 결과
20장 한도·기존 19장·동시 8건 테스트에서 최종 20장 유지, 7건 거부.
트레이드오프
같은 사용자의 요청은 잠금을 기다립니다. 짧은 트랜잭션, 일관된 잠금 순서, 타임아웃과 재시도 정책이 필요합니다.
배운 점
애플리케이션 검증만으로는 충분하지 않습니다. 정합성의 경계를 트랜잭션으로 묶어야 합니다.
성능 측정 기록
출처: 작성자가 제공한 NEMO 측정 결과. 시뮬레이션 값이 아닙니다. 하드웨어·데이터 규모·반복 횟수·측정 도구·격리 수준·측정일과 원본 보고서는 추가 기록이 필요합니다. 다른 환경에서 같은 결과를 보장하지 않습니다.
측정 근거와 재현 조건
- 출처
- NEMO 프로젝트 · 작성자 제공 측정 결과
- 환경 / 방법
- 미등록 · 원본 테스트 환경 확인 후 기재
- 측정일 / 원본 링크
- 미등록 · 원본 보고서 미연결