[개발 리포트] Monew 프로젝트
1. 프로젝트 개요
- 서비스 명: Monew (관심 뉴스 구독 및 커뮤니티 서비스)
- 목적
- 사용자 맞춤형 관심사 기반 뉴스 수집/제공 및 활동 내역 조회 및 알림 시스템 구축
- 주요 기능
- 관심 키워드 기반 뉴스 수집 및 구독 기능
- 관심 뉴스 등록 및 좋아요 알림 서비스
- 활동 로그 기반의 마이페이지 통계 및 내역 관리
2. 담당 작업
- 알림 관리 API: 이벤트 기반 알림 아키텍처 설계, 알림 조회 및 벌크 업데이트 구현
- 배치 처리: 확인 알림 자동 삭제 배치 구현 (
Spring Batch) - 인프라 및 CI/CD: AWS ECS 환경 구축, Docker Multi-stage 빌드 최적화, GitHub Actions 파이프라인 구성
- 성능 및 테스트: Locust 기반 부하 테스트 시나리오 작성, Testcontainers 기반 통합 테스트 환경 표준화
3. 기술적 성과
- 이벤트 기반 알림 시스템: Spring Event와
TransactionPhase.AFTER_COMMIT을 활용하여 메인 로직 성공 시에만 알림이 저장되는 안정적인 비동기 구조 확립 - 배치 작업 최적화: Native Query와 Limit 절을 조합한 분할 삭제 방식을 도입하여 배치 실행 시 DB 락(Lock) 경합 최소화
- 품질 관리 지표: Jacoco를 활용한 엄격한 테스트 관리로 최종 테스트 커버리지 85% 달성(TDD 도입)
- AWS Lambda 함수 사용: 로그를 직접 S3 버킷에 백업하지 않고 Lambda와 이벤트 스케줄러를 사용하여 서비스 외부에서 자동화
- CI/CD 배포 파이프라인: ECS Task Definition을 json으로 정의하여 IaC로 배포 파이프라인 구축
4. 문제 해결 과정
[문제 1] 알림 내역 조회 성능 저하 (복합 인덱스 활용)
- 상황
- 사용자 알림 내역 조회 시 데이터 누적에 따른 응답 속도 저하 발생
- 분석
- user_id, is_confirmed, created_at 등 여러 조건이 혼합된 쿼리에서 풀 스캔 발생
- 해결
- 최적의 복합 인덱스(Composite Index) 설계 및 쿼리 튜닝
- 결과
- 대량 데이터 환경에서도 일정한 수준의 알림 조회 성능 확보 및 서버 리소스 절감
- 관련 PR 및 이슈
- ㅇ
[문제 2] 통합 테스트 환경 개선 (Testcontainers 활용)
- 상황
- 테스트에서 사용하는 H2 환경과 실제 운영 환경(PostgreSQL)의 문법 및 제약 조건 차이로 인한 테스트 일관성 보장 X
- 분석
- 인메모리 DB의 한계로 인해 실제 DB 전용 쿼리나 제약 사항 검증 불가 → 테스트 결과가 매번 바뀜
- 해결
- 통합테스트에서 Testcontainers 라이브러리를 도입하여 도커 컨테이너 기반의 독립적인 테스트 환경 구축
- 결과
- 실제 서비스 환경과 동일한 상태 유지 및 CI/CD 환경에서도 테스트 정합성 보장
- 관련 PR 및 이슈
- ㅇ
[문제 3] 멀티 스레드 환경에서 동일 시간 배치 작업 기록 실패 (격리 수준 변경)
- 상황
- 동일 시간에 실행되는 배치 작업의 경우(정각-뉴스수집, 특정 정각시간-삭제 작업) 한 개의 작업이 실패하는 문제 발생
- 분석
- 로그 분석 결과 데이터베이스에 배치 작업 기록 시도 시에, SERIALIZE 설정으로 하나의 작업만 성공하고 나머지 실패
- 데이터베이스 배치 작업 테이블의 격리 수준 확인 결과, READ_COMMITTED 으로 테이블 문제가 아닌 것을 확인
- 기존 BatchConfig에서 기본 스프링 배치 설정 사용으로 인해 SERIALIZE 설정 적용인 것을 확인
- 해결
- BatchConfig가
DefaultBatchConfiguration를 상속받도록 하고getIsolationLevelForCreate()을 오버라이딩하여 격리 수준을 READ_COMMITTED으로 변경
- BatchConfig가
- 결과
- 멀티 스레드로 동시에 여러 배치 작업이 실행되어도 데드락 발생 X
- 관련 PR 및 이슈
- ㅇ
[문제 4] 관심사 이름 순 정렬 실패 (COLLATE “ko-KR-x-icu” 설정)
- 상황
- 관심사 이름으로 정렬 시, 한글에서 정렬 순서가 꼬이는 문제 발생
- 분석
- Postgres의 기본 COLLATE 설정이 영어로, 한글 정렬이 제대로 반영 X
- 전체 DB에 “ko-KR-x-icu” 설정을 위해서는 처음 생성 시 적용 필요하나 이미 서비스가 운영 중
- 해결
- 관심사 테이블에만 정렬 조건 적용(한글 정렬이 필요한 유일한 테이블임으로)
ALTER TABLE interests ALTER COLUMN name TYPE VARCHAR(100) COLLATE "ko-KR-x-icu"; - 결과
- 한글 정렬 성공
- 관련 PR 및 이슈
5. 협업 및 피드백
- 한글 정렬 문제
-
데이터베이스를 새로 생성하고 기존 데이터를 옮기는 방식 대신 서비스 코드에서 해당 열 조회 시 쿼리문에 “ko-KR-x-icu” 조건을 넣는 것 고려하고 담당자가 진행하였으나, 단위 테스트에서 h2를 사용하여 해당 쿼리문이 유효하지 않아 테스트 검증이 실패하는 문제 발생
→ sql 문으로 해결 → 기존 sql 스크립트에 반영
-
6. 코드 품질 및 최적화
1) TDD 방식 도입
- 상황
- TDD 방식을 도입하여 개발을 진행
- 결과
- RED-GREEN-REFACTOR 과정에서 발생할 수 있는 예외를 미리 처리함으로써 코드의 안정성 향상
- 다른 도메인과 연결된 경우에도 테스트 코드에서 여러 상황을 가정하여 작성하여 오류 발생 X
- 관련 PR 및 이슈
- ㅇ
2) Dev Branch PR Convention
- 상황
- Dev 브랜치 PR 시 자동으로 테스트가 실행되도록 워크 플로우를 구성하고 CodeCov 설정을 추가하여 새로운 PR 내역의 커버리지의 테스트 조건을 70%를 넘길 것을 강제
- 초기 개발 이후 전체 커버리지 70% 이상을 달성하고, 전체 커버리지 조건 추가
- 결과
- 최종 커버리지 90% 달성
- 관련 PR 및 이슈
- ㅇ
7. 향후 개선 사항
- 대량의 관심 기사 등록 알림 처리를 위한 Spring Batch 전환 및 벌크 인서트 적용
- CI/CD 배포 파이프라인에서 ACCESS KEY 인증 방식에서 Role 기반의 OIDC 방식으로 전환
- 일부 기능에 캐시를 도입하여 서비스 성능 개선
- K6와 같은 다른 종류의 부하테스트 도구 활용
- Grafana 또는 Prometheus 활용
- 도메인 중심 패키지 구조로 변경
Leave a comment