K-L1VERSE

DDD(Domain Driven Development, 도메인 주도 개발)를 활용한 MSA 설계

ignuy 2024. 9. 12.

안녕하세요. 케이리버스의 PM, Aiden입니다. 프로젝트가 끝난 지 약 3개월 만에 첫 회고를 작성해 보네요. 애정 있던 프로젝트였고 개발에도 적극적으로 참여했던 프로젝트를 다시 시작하게 될 예정이라 기대감으로 가슴이 불타고 있습니다. 🔥🔥 그런 의미로 더 특별해진 제 첫 회고는 바로 케이리버스의 시작이었던 설계입니다.

요구사항 분석

국내 K-리그의 흥행을 위해 기획된 K-리그 커뮤니티 SNS 서비스 K-L1VERSE는 기존 케이리그 팬덤과 새로운 유입층을 아우르는 서비스로 개발되고자 하였습니다. 설정한 페르소나를 바탕으로 요구사항을 수집하였고 아래와 같이 다양한 기능적 요구사항들을 정의하였습니다.

* 사용자 기능
	- 소셜로그인
	- 포인트 제도
	- 응원팀 뱃지
* SNS 커뮤니티 기능
* 팀 추천 유저 성향 설문 기능
	- SNS(카카오톡)를 활용한 결과 공유 기능
* 경기 정보 기능
	- 경기 일정 확인
	- 경기 상세 정보
	- 실시간 채팅
... (생략)

검토

SSAFY의 프로젝트 기간은 약 6주로 이 기간안에 요구사항을 구현하는 데에 있어 기술적, 경제적 타당성을 검토해야 했습니다.

6명의 팀원들의 기술적 숙련도를 확인한 결과 프로젝트에 필요한 핵심 기능(SNS 기능, 크롤링 등)이 구현 가능한지에 대해서는 불안 요소가 없었으며 SSAFY에서 지원하는 서버, RDS를 활용하여 경제적으로도 무리 없는 프로젝트라고 결론지었고 본격적인 시스템 설계에 착수하였습니다.

시스템 설계

DDD(Domain-Driven Development, 도메인 주도 개발)

Context 분리

K-L1VERSE는 위에 도출된 요구사항처럼 한 번에 구분 짓기 어려운 복잡한 영역에서 기능을 가진다는 특징이 있었습니다. 고민을 거듭해도 문제의 영역이 너무 크다고 느꼈고 분할&정복의 필요성을 생각하게 되었습니다.

K-L1VERSE를 축구 커뮤니티라는 도메인으로 하나의 큰 그림으로 생각하고 기능들을 성격에 맞게 분류하였습니다. 여기서 도메인이란 소프트웨어가 해결하고자 하는 문제 영역을 의미합니다. 저희 팀은 이를 SW 구현의 관점에서 Context라는 해결의 영역으로 나누어야 했습니다.

Bounded Context 정의

다음 단계로 Bounded Context를 정의했습니다. Bounded Context란 도메인 모델을 적용할 범위를 한정하는 개념으로 도메인의 일부 기능 또는 비즈니스 프로세스를 다루는 단위입니다.

K-L1VERSE는 그렇게 각자 문제 해결에 집중할 범위(Context)인 유저, 설문경기, SNS 기능으로 쪼개어지게 되었습니다.

간단하게 다이어그램을 그렸을 때 위와 같이 Bounded Context가 구성됩니다. 설문 Context는 다른 Context와는 전혀 관여하지 않는 별개의 영역으로 설계되어 있습니다.

또한, 경기 Context와 유저 Context가 “사용자 포인트”라는 데이터를 공유하며 고객-공급자 관계(Customer-Supplier)를 가지고 SNS Context와 유저 Context 또한 유저 데이터로 고객-공급자 관계를 가지고 있습니다. 고객-공급자(Customer-Supplier) 관계란 공급자 컨텍스트가 데이터를 제공하고, 고객 컨텍스트가 이를 소비하는 관계입니다. K-L1VERSE에서는 유저 Context가 두 관계 모두 공급자 컨텍스트를 담당하고 있습니다.

MSA 설계

Bounded Context를 정의하고 나니 기능 간의 논리적 경계가 뚜렷해지고 이를 그대로 마이크로서비스로 옮겨 시스템 아키텍처를 구성하는 것이 설계상으로 유리하다고 판단하였습니다. 각 서비스를 독립적으로 개발 및 배포할 수 있게 되었고 독립적으로 배포 가능한 서비스는 시스템의 변경이 다른 부분에 영향을 미치지 않게 하여 개발의 유연성을 높일 수 있을 것이라고 판단했습니다. MSA를 선택하게 된 것은 DDD 채택에 따른 개발 측면에서의 장점뿐만 아니라 운영 측면도 고려한 결정이었습니다. K-L1VERSE의 경기 Context의 주요 기능들은 아래와 같습니다.

* 경기 정보 기능
	- 경기 일정 확인
	- 경기 상세 정보
	- 실시간 채팅
	- 등등

해당 기능들은 꾸준히 사용자 트래픽이 발생하기보다 K리그 매치 데이의 일정에 맞게 사용자 트래픽이 증가하고 감소하는 경향을 보일 것이라 예상되었습니다.

반면, SNS 기능, 팀 추천 유저 성향 설문 기능은 한순간에 트래픽이 몰리기보다 꾸준히 사용자 트래픽이 발생할 것이라 예상되었습니다. 이처럼 각 서비스를 독립적으로 배포하여 필요한 경우 개별적으로 스케일링하는 것이 운영 측면에서 K-L1VERSE에게 유리한 결정이라고 판단하여 MSA를 채택하게 되었습니다.

DB 설계

DDD + MSA를 선택하게 되면서 각 서비스를 완전히 물리적으로 분리시켜 서비스 결합도를 낮추고자하였고 그 결과 데이터베이스도 물리적으로 분리하여 관리하게 되었습니다.

잘 보이진 않으시겠지만,,, 그룹 내 테이블 구조라 명확히 공개하기도 좀 그래서ㅠㅠ

위 ERD는 K-L1VERSE의 context 간의 데이터 구조를 보여주고 있습니다. 각 기능 context를 테이블 색으로 구분하고 있습니다. DB의 물리적으로 완전한 분리를 위해선 테이블 간의 연결된 연관관계를 끊어내고 따로 데이터 정합성을 고려할 필요가 있었습니다. 이를 위해 SAGA 패턴을 도입하기로 결정하였습니다. SAGA 패턴에 대해서는 따로 자세한 활용 방법에 대한 소개 회고를 계획 중이라 이번 회고에서는 내용에서 제외하겠습니다.

조금 아쉬웠던 점은 6주라는 개발 기간 동안 유저와 경기 context를 완전히 분리시키는 것은 가능했지만 유저와 SNS context를 분리시키는 것은 현실적으로 무리인 일정이라고 판단하여 이 부분은 DB를 분리하지 못하였습니다.

최종적으로

그렇게 완성된 프로젝트 구조도는 다음과 같습니다. 초기 설계에서는 유저, SNS, 경기, 설문 총 4개의 서비스를 계획하고 개발을 진행하였지만 최종적으로 Django를 활용한 클린봇, 실시간 크롤링을 위한 크롤링 서비스가 프로젝트 아키텍처에 추가되어 총 6개의 서비스가 올라가게 되었습니다. 모든 서비스는 Spring Cloud Gateway라는 하나의 API 진입점을 지나게 되어 유지보수성을 높였습니다. 또한, 서버 간의 통신은 Apache Kafka를 이용하여 중개하였습니다.

 

여기까지 K-L1VERSE의 프로젝트 설계 이야기였습니다. K-L1VERSE는 이제 프로젝트 개선 리팩토링 단계에 접어들었습니다. 당분간 아키텍처가 변동되는 일은 없을 것으로 보이지만 MSA로 서비스를 구축한 덕에 확장과 변경에 자유롭다는 점이 매력적인 프로젝트였습니다. 앞으로 구현해보고 싶은 기능들이 많습니다. “축구 선수를 위한 라이브 스트리밍”, “축구 입문자를 위한 챗봇 기능” 등 다양한 기능을 올리고 완성되어 갈 K-L1VERSE를 응원해 주시길 바라겠습니다. 긴 글 읽어주셔서 감사합니다.

'K-L1VERSE' 카테고리의 다른 글

Lightsail vs EC2  (0) 2024.09.12

댓글