Bookking
📅 기간: 2025.04 ~ 2025.05 (2개월)
👥 팀원: BE 5명
GitHub 저장소 방문하기
✨ 프로젝트 소개
BookKing은 사용자의 복잡한 키워드 검색 조건에도 빠르고 정확하게 응답하는 것을 목표로 하는 도서 검색 서비스입니다.
백엔드 개발자로서, 최적의 검색 성능을 내기 위해 다양한 기술 스택을 주도적으로 탐색하고 적용하는 것이 첫 번째 목표였습니다. 또한, 프로젝트 기간 동안 총 3번의 점진적인 리팩토링을 통해 시스템의 확장성과 유지보수성을 지속적으로 개선하는 것을 핵심 과제로 삼았습니다.
🛠 기술 스택
- Spring boot
- Spring boot Data JPA
- MySQL
- AWS
- Grafana
- Jenkins
- SonarQube
- ELK
- Redis
- Cloudflare
- Nginx
- Swagger
💪 맡은 기능 구현
-
결제 도메인 동시성 제어 리팩토링 (DB Lock → Redisson)
- 한계 인식: DB Pessimistic Lock의 성능 저하(DB 병목) 문제를 인지하고, 8%의 성능 향상과 수평 확장성(Scale-out)을 확보하기 위해 Redisson 분산 락으로 리팩토링을 주도했습니다.
- 기술 선택: DB 부하를 줄이고 애플리케이션 레벨에서 락을 관리하는 Redisson이 다중 서버 환경에 더 유연하다고 판단하여 적용했습니다.
-
HTTPS 아키텍처 개선 및 AWS 인프라 통합 (Cloudflare → AWS Native)
- 문제 해결: 1차 구현(Cloudflare) 시 발생한 170~250ms의 응답 지연 문제를 해결하기 위해, AWS Native 서비스로 아키텍처를 변경했습니다.
- 성과: Route 53, ACM, ALB를 연동하여 트래픽이 AWS 내부에서 처리되도록 개선, 응답 속도를 20~30ms로 안정화하고 ECS/ALB 환경의 운영 효율성을 확보했습니다.
-
CI/CD 파이프라인 고도화 및 코드 품질 관리 (GitHub Actions → Jenkins + ECS)
- 파이프라인 구축: 프로젝트가 v2(다중 앱)로 확장됨에 따라, 비용과 유연성을 고려해 GitHub Actions에서 Jenkins로 마이그레이션했습니다.
- 코드 품질 통합: CI 파이프라인에 SonarQube(SonarCloud)를 통합하여 정적 분석을 자동화, 코드 스멜을 52개에서 26개로 50% 감소시켰습니다.
- 배포 자동화: Jenkins와 AWS ECS(Fargate)를 연동하여, Docker 이미지 빌드부터 ECR 푸시, ECS 무중단 배포까지의 CD(지속적 배포) 파이프라인을 완성했습니다.
🔍 트러블 슈팅
1. Redisson 락과 트랜잭션의 순서 문제 해결
문제 상황
Redisson 분산 락을 적용했음에도, 부하 테스트(가상 유저 1천 명) 시 1.44%의 재고 불일치(레이스 컨디션)가 발생하는 것을 발견했습니다.
원인 분석
원인은 @Transactional의 AOP 동작으로 인해, 트랜잭션이 커밋되기 전에 락이 먼저 해제되는 순서 문제였습니다. 이로 인해 다른 스레드가 커밋 전 데이터를 읽어가는 문제가 발생했습니다.
해결
Facade 패턴을 도입하여 락과 트랜잭션의 생명주기를 명확히 분리했습니다. 락 획득 로직을 트랜잭션 로직(@Transactional)의 외부로 감싸, [락 획득 → 트랜잭션 시작 → 트랜잭션 커밋 → 락 해제] 순서가 항상 보장되도록 구조를 변경했습니다.
결과
동일한 부하 테스트 환경에서 재고 오류율 0%를 달성하며, 동시성 문제를 근본적으로 해결하고 데이터 정합성을 확보했습니다.
2. ECS 배포 실패 (OUT_OF_SERVICE) 원인 분석
문제 상황
ECS 배포 시 ALB 헬스체크가 실패하며 OUT_OF_SERVICE가 발생했습니다.
원인 분석
- 상세 원인 확보: 헬스체크의 세부 정보를 보기 위해, Actuator의
show-details를 ALWAYS로 임시 변경했습니다.
- 근본 원인 특정: 헬스체크 응답 상세 내용에서 Elasticsearch가
OUT_OF_SERVICE 상태임을 확인했습니다.
- 로그 확인: ES 컨테이너 로그 분석 결과, 재시작 시 한글 형태소 분석기 config 파일이 누락되어 ES가 구동에 실패한 것을 발견했습니다.
해결
Docker volume을 설정하여, config 파일이 컨테이너가 재시작되어도 영속적으로 마운트되도록 조치했습니다.
결과
ES가 정상 구동되면서 전체 헬스체크가 IN_SERVICE로 복구되었고, ECS 배포에 성공했습니다.
📈 발전 사항
Redis를 활용한 API 성능 최적화
한계 및 목표: 현재 Redis가 분산 락 기능으로만 한정적으로 사용되고, API는 캐시가 없어 매번 DB를 조회하는 비효율이 있습니다.
개선 방안: Redis의 활용도를 높여, 자주 조회되는 DB 데이터를 캐싱하고 Access Token 등 인증 정보를 저장하는 중앙 캐시 저장소로 확장하고자 합니다.
기대 효과: DB 부하를 크게 줄이고, 사용자의 API 응답 속도를 향상시킬 수 있습니다.