Skip to content

team-serius/doldol-server

Repository files navigation

모이면 완성되는 마음의 종이, 돌돌

🌟 서비스 소개

'돌돌'은 소중한 사람들과 함께 마음을 주고받는 온라인 롤링페이퍼 서비스입니다. 직접 만나기 어려운 상황에서도 따뜻한 메시지를 주고받으며 서로의 소중한 순간을 함께할 수 있도록 기획되었습니다. 생일, 졸업, 기념일 등 특별한 날, 친구, 가족, 동료들에게 진심을 담은 롤링페이퍼를 선물해 보세요!

✨ 주요 기능

  • 간편한 롤링페이퍼 생성: 몇 번의 클릭만으로 나만의 롤링페이퍼를 만들 수 있습니다.
  • 롤링페이퍼 공유: 원하는 사람들에게 링크를 공유하여 롤링페이퍼에 초대해보세요!
  • 메시지 공개 날짜 설정 : 특정 날짜 이전까지는 메시지가 보이지 않도록 설정할 수 있습니다. 이를 통해 미래에 보내는 편지를 보내보세요.

🚀 프로젝트 개요 및 개발 과정

'돌돌 서버' 프로젝트는 개발 동아리 시리우스에서 4명의 백엔드 개발자가 협력하여 진행되었습니다.


💻 BE 팀원 소개

개발자 담당 기능
김동윤
김동윤
(BE-PO)
• API 명세서 작성
• ERD 구성
• CI/CD 파이프라인 구축
• 무중단 배포
• 인증/인가 (소셜 로그인 유저와 자체 서비스 로그인 유저를 통합 관리)
• 메시지 CRUD • 로그/서버 모니터링
최이주
최이주
(BE-PM)
• 롤링페이퍼 작성 CRUD
• AWS 세팅
• 전반적인 Git 관리
서상훈
서상훈
(BE-Member)
• 테이블 설계 및 ERD 구성
• 메세지 신고 API 개발 (페이지네이션 적용)
• 서버 CPU 사용량 알림 시스템 구축
문정우
문정우
(BE-Member)
• API 명세서 작성
• Spring 초기 설정
• 이슈 및 PR 템플릿 작성
• 유저 정보 조회 API

🛠️ Tech Stack

doldol_be_icon doldol_infra_icon


🛠️ ERD

image

🛠️ API 명세서

Swagger UI에서 API 명세서 확인하기


🛠️ BE Infra

doldol_architecture

👨‍💻 개발자별 고민사항 및 해결과정

👤 개발자 🤔 고민사항 💡 해결과정
김동윤
김동윤
(BE-PO)
Q1. 백엔드 서버를 Public Subnet에 위치시킨 이유 보안 측면에서는 Private Subnet에 RDS와 EC2를 배치하는 것이 더 안전합니다. 하지만 소셜 로그인 구현 시 Private Subnet의 EC2에서 외부 OAuth 서버로 API 요청을 보내기 위해서는 NAT Gateway 또는 NAT Instance와 같은 추가 인프라가 필요합니다.

초기 개발 단계에서 인프라 복잡도와 비용을 고려하여 Public Subnet을 선택했으며, 대신 Security Group을 통해 보안을 강화했습니다.

📝 참고 블로그
Q2. CI/CD 툴 선택 이유 t2.micro EC2 인스턴스는 메모리 용량이 제한적이어서 Jenkins를 Docker로 구동할 경우 메모리 스왑이 발생할 수밖에 없었습니다. 메모리 스왑은 성능 저하를 유발할 수 있어 지양했습니다.

GitHub Actions는 프라이빗 레포지토리에 대해 월 500MB, 2,000분의 무료 사용량을 제공하며, 파이프라인 구성이 Jenkins에 비해 간단하고 직관적이어서 생산성을 높일 수 있다는 점에서 선택했습니다.

📝 참고 블로그
Q3. CI와 CD 워크플로우 구성 전략 무중단 배포(Blue-Green Deployment)를 도입했기 때문에, 배포 시 안정성과 신중함이 중요했습니다. 따라서 CD 과정은 자동이 아닌 수동 트리거 방식으로 구성하였고, latest 버전과 롤백 시 사용할 이전 버전을 명시적으로 입력받아 배포하도록 설계했습니다.

이를 통해 배포 시 발생할 수 있는 리스크를 최소화하고, 빠르게 복구할 수 있는 구조를 갖추었습니다.
Q4. 데이터 암호화 범위 결정 데이터는 민감도와 사용 목적에 따라 선택적으로 암호화하는 것이 중요하다고 생각합니다. 비밀번호는 해싱 방식으로 처리하고, 메시지처럼 다시 보여줘야 하는 정보는 복호화 가능한 암호화를 적용했습니다.

고정 Salt를 사용한 암호화는 보안에 취약하며, 복호화 과정에서 페이지 렌더링 지연과 서버 CPU 과부하가 발생할 수 있어 메시지 내용과 비밀번호에만 암호화를 적용했습니다.

📝 참고 블로그
Q5. 로그를 어떻게 관리할까? 먼저 INFO 단계까지의 로그를 모두 수집하면 비용이 꽤 많이 들겠다는 판단을 했습니다. 특히 local이나 dev 환경에서는 굳이 로그를 수집하지 않아도, 테스트 중에 직접 저장된 로그 파일을 확인하거나 컨테이너의 실시간 로그를 보는 방식으로도 충분하다고 느꼈습니다.

하지만 운영 환경은 상황이 달랐습니다. 실제 사용자들이 많이 접속하고, 문제가 발생했을 때 빠르게 원인을 파악하려면 로그가 체계적으로 수집되고, 실시간으로 모니터링되는 시스템이 필요하다고 판단했습니다. 그래서 운영 단계에서는 로그 수집 및 모니터링 시스템을 도입해, 장애 대응과 문제 해결을 보다 효과적으로 할 수 있도록 구성했습니다.

📝 참고 블로그
서상훈
서상훈
(BE-MEMBER)
Q1. N+1 문제 해결 방법 처음에는 JPA의 기본 지연 로딩 때문에 신고 목록을 조회할 때마다 각각의 신고에 대해 신고당한 메시지 정보를 가져오기 위해 추가 쿼리가 발생하는 전형적인 N+1 문제였습니다. 100개의 신고를 조회하면 총 101개의 쿼리(1 + 100)가 실행되어 성능이 심각하게 저하되었어요. 이를 해결하기 위해 먼저 fetch join을 고려했지만, 전체 엔티티를 로딩하면 메모리 사용량이 과도해질 것 같았습니다. 그래서 QueryDSL의 DTO 프로젝션 기능을 활용해 필요한 컬럼만 선택적으로 조회하면서 동시에 join을 통해 연관 데이터를 한 번에 가져오는 방식으로 최적화했습니다. 결과적으로 쿼리 수를 101개에서 1개로 줄이고, 불필요한 엔티티 생성 오버헤드도 제거할 수 있었습니다.
Q2. 서버를 안정적으로 유지할 수 있는 방법 뉴스에서 서버 장애 대응을 위해 직원들이 주말에도 출근하는 모습을 보고, 우리 서비스도 예상치 못한 상황에 대비해야겠다고 생각했어요. 그래서 CPU 사용률 알림 시스템을 도입하기로 했습니다. AWS CloudWatch를 활용해서 CPU 사용률이 임계치(80%)를 초과하면 자동으로 알람이 발생하도록 설정했어요. 이 알람이 Lambda 함수를 트리거하고, Lambda에서 SNS를 통해 메시지를 받아 Slack Webhook API로 개발팀 채널에 실시간 알림을 보내는 구조를 만들었습니다. CloudWatch → Lambda → SNS → Slack으로 이어지는 자동화 파이프라인을 구축해서, 서버에 이상이 생기면 즉시 알림을 받을 수 있게 되었어요. 알림만으로도 상황을 빠르게 파악하고 대처할 수 있겠다는 생각이 들어서 이 시스템을 도입하게 되었습니다.

About

모두가 함께 만드는 온라인 롤링페이퍼 🗞️

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages