https://www.miricanvas.com/v/13r3bod
1분 내외로 찍기
서비스 아키텍처
다음은 백엔드의 서비스 아키텍처를 살펴보겠습니다.
저희 문코 서비스의 핵심은 CQRS와 이벤트 소싱 패턴의 적용에 있습니다. RDS는 쓰기 작업을, DynamoDB는 읽기 작업을 담당하며, CQRS를 구현하였습니다. 이벤트 소싱을 통해 상태 변경을 이벤트로 저장하고 처리하였습니다. 이를 통해 백엔드 서버는 높은 처리량과 낮은 지연 시간 그리고 데이터 일관성의 성능을 유지하고 있습니다.
또한, Docker와 Nginx를 활용하여 서비스 간 격리와 독립적인 스케일링을 가능하게 하는 구조로 궁극적으로 마이크로서비스로의 전환을 준비하는 첫 걸음으로써 이러한 구조를 설계하였습니다.
더불어, Prometheus와 Grafana를 통한 실시간 모니터링과 장애감지, GitHub Actions를 통한 CI/CD 파이프라인은 빠른 개발 주기와 안정적인 배포를 보장하기 위한 인프라 구축에도 상당한 노력을 기울였습니다.
트러블슈팅 1 - NoSQL 호환 문제
저희 백엔드 팀에서 초기 배포 당시 읽기 작업을 담당하는 MongoDB 호환 서비스로 Amazon DocumentDB를 선택했으나, EC2 ubuntu 환경과 DocumentDB 간 호환성 문제가 발생했습니다.
이 문제를 해결하기 위해, 아키텍처를 재검토하고 DyanmoDB로의 전환을 결정하였습니다.
DynamoDB는 연결 세션을 필요로 하지 않는 완전 관리형 NoSQL 데이터베이스 서비스입니다. 이 의사결정으로 DB 커넥션 문제를 해결하였고 결과적으로 시스템의 안정성과 읽기 성능이 크게 향상되었습니다. 다시 한번 클라우드 네이티브 환경에서의 데이터베이스 선택과 마이그레이션의 중요성을 깨닫게 되었습니다.
트러블슈팅 3 - CQRS 및 이벤트 소싱 이슈
NestJS의 내장 이벤트 버스로 인한 지연과 확장성 제한을 극복하기 위해, 커스텀 EventBusService를 구현했습니다. 이로써 비동기 처리가 가능해져 지연 문제를 해결할 수 있었고, 시스템의 안정성과 확장성이 크게 개선되었지만, 앞으로 Apache Kafka 통합을 통한 더 강력한 이벤트 스트리밍 구현이 필요합니다. 끊임없이 발생하는 이벤트와 트랜잭션을 더욱 안정적으로 처리하기 위해서 수료 이후 점진적으로 이벤트 드리븐 아키텍처로의 점진적 개선에 도전해보려고 합니다.
트러블 슈팅 4
DynamoDB 업데이트 전 Postgres의 선응답 문제를 해결했습니다. 주소록 현재 위치 설정 시 읽기 DB에 업로드되기 전 응답이 발생하는 문제를 이벤트 캐싱을 도입하여 해결했습니다. 이를 통해 이벤트 완료 후 컨트롤러에서 캐시를 통해 응답을 확인할 수 있게 되었습니다.
트러블 슈팅 5
거리 기반 추천 시스템의 성능 문제를 개선했습니다. DynamoDB에 과도한 부하가 발생하는 문제를 해결하기 위해, 추천 로직을 거리 계산과 문코 추천으로 분리하고 Redis의 geoadd 함수를 활용하여 부하를 분산시켰습니다. 이로 인해 전반적인 시스템 성능이 크게 향상되었습니다.
예상 질문
CQRS 사용이유
이러한 이유로 CQRS와 이벤트 소싱은 우리 시스템의 성능, 확장성, 그리고 유지보수성을 크게 향상시키는 핵심 아키텍처 패턴이 되었습니다.