Q. 서비스를 어떻게 나누었나?
기획 단계에서 유저 스토리를 작성했습니다.
사용자가 무엇을 원하는지에 대한 요구사항서를 작성한 것인데 이에 따라 스토리 보드를 그려가며 모놀리딕한 형식으로 서비스 플로우를 구성했습니다.
이슈 넘버로 기능을 명시했고 플로우가 끊기는 부분으로 덩치를 나누었습니다. 이 과정을 통해 저희 팀은 후보 서비스 도출을 진행했습니다.
해당 플로우를 바탕으로 와이어프레임을 제작했습니다. 와이어 프레임을 제작해나가면서 사용자 관점에서 어플리케이션을 사용할 때 서비스 레벨로 분리되는 부분들이 보였습니다.
분리 기준은 한 서비스의 장애에 있어서 독립적으로 운용이 가능한가? 서비스 간 분산 트렌젝션을 진행할 때 데이터간 일관성/정합성에 큰 무리가 가지 않는가? 로 정했습니다.
도메인 친화적으로 서비스 이름을 짓기 위해 그룹 바깥 서비스는 suite_room_service로, 그룹 내부 서비스는 study_room_service로 약속했습니다.
그리고 다시 한 번 체크했습니다. 서비스를 나누는 기준으로는 크게 DDD, 업무 기능 관점, 확장/배포/독립/장애대응 용이성, 변경 가능성, 트렌젝션과 일관성이 있는데 저희 팀의 MSA 운용 목적은 어플리케이션의 고가용성과 분산 트렌젝션의 안정성, 변경 가능성이였으므로 서비스 분리에 대한 근거를 제시할 수 있다고 판단했습니다.
후보 서비스들을 대략적으로 선정한 후 서비스의 크기에 대해서 생각을 해보았습니다.
결제 서비스 분리
먼저 결제 서비스의 경우 단순히 외부 결제 모듈에 API 콜 정도로 간단한 기능을 제공하지만 분리한 이유는 첫 번째로 기술/환경/조직 에 따른 자유로운 서비스 구성 목적입니다.
결제 모듈을 다루는 서비스를 Node.js 프레임워크로 다루어 비동기 처리에 대해 수월한 처리를 하기 위함입니다.
두번째로 Suite Room 서비스에서 결제 모듈을 콜 하는 것도 가능하지만 서비스의 단일 책임 원칙을 최대한 지키기 위함과 서비스의 볼륨이 너무 커지는 것을 막기 위해서입니다.
Suite Room / Study Room 서비스 병합
서비스를 두 개의 서비스로 분리했을 때 얻을 수 있는 고가용성의 이점보다 보상 트렌젝션 처리, 데이터 일관성 문제, 캐시 처리 등의 단점이 더 많다고 생각해 두 서비스를 하나의 Suite Room Service 로 병합했습니다.
미션과 출석 서비스 병합 ( 스터디 서비스 )
이 두 서비스는 모두 집계를 위한 서비스인데 데이터를 핸들링하기 위해 잦은 서비스간 호출이 발생한다 생각했고 이에 대해 보상 트렌젝션 처리가 복잡하지는 상황을 막기 위해서 병합했습니다.
추가로 이 두 서비스를 분리했을 때 얻는 이점도 따로 없을 뿐더러 두 서비스가 집계 의 단일 원칙을 위배하지 않는다고 판단했습니다.
추가로 변경 가능성의 관점에서 보았을 때 추후 도입될 스터디가 진행될 때 제공하는 서비스가 추가될 수 있기에,스터디 서비스로 분리했습니다.
명예의 전당 / 유저 일반 정보 서비스 병합
이 두 서비스의 경우 작업의 성격이 동일합니다. 통계 의 단일 원칙을 공통적으로 가지고 있고, 분리했을 때의 서비스가 서비스 단위로 나누어지는 것이 아니라 태스크 단위로 나누어지기 때문에 병합했습니다.
명예의 전당 -> Suite Room 서비스로 편입
단순 READ만 존재하는 서비스이며, Suite Room 내부에 있는 데이터를 쿼리문을 통해 필터링 하는 기능만 수행하기 때문에 DDD 관점에서 병합하는게 맞다고 판단
사용자 스터디 정보 서비스 병합 -> 스터디 서비스로 편입
단순 READ만 존재하는 서비스이며, 스터디 서비스 내부에 있는 데이터를 쿼리문을 통해 필터링 하는 기능만 수행하기 때문에 DDD 관점에서 병합하는게 맞다고 판단하
알림 서비스 분리
우선 알림 서비스를 어느 서비스에 종속시키기에 단일 책임 원칙에 위배되기 때문입니다. 알림에 대한 모든 로직을 해당 서비스에서 처리할 수 있고 일반적으로 알림 서비스는 많은 트래픽을 처리해야 하기 때문에 알림 처리에 대한 로직이 다른 서비스에 흩어져 있지 않아서 관리가 수월합니다. 따라서 서비스를 분리했습니다.
API First Design
이렇게 분리한 서비스를 가지고 저희는 클래스 다이어그램을 작성했습니다. 서비스들이 어떤 컴포넌트를 가지고 오퍼레이션을 제공하는지, 그리고 어느 부분에서 API를 공개해 다른 서비스와 통신하는지에 대한 개요를 그려서 팀원들간 구조적 서비스 플로우에 동기화를 위함입니다.