이번 포스팅에서는 프로젝트에 MSA를 적용하기 위해 어떤 기준으로 서비스를 분리하고 어떻게 관리할 지 설계하는 과정에 대해서 다룬다.
MSA에 대해 알아보기 전에 Monolithic Architecture 부터 알아보자.
Monolithic Architecture 는 전통적인 개발 방식으로 하나의 프로젝트에 서비스의 모든 기능을 개발하고 배포하는 방식이다.
Monolithic Architecture 는 우리에게 (적어도 나에겐) 익숙하고 설계와 관리가 쉬운 편이다. 그런데 왜 MSA 라는 방식이 도입되기 시작했을까?
다음은 Monolithic Architecture 에서 단점으로 비롯되는 문제의 예시이다.
A 포탈 사이트는 Monolithic Architecture 로 개발된 메일, 카페, 블로그, 웹툰, 쇼핑 등의 다양한 서비스를 제공한다. 어느날 쇼핑 서비스에서 특가 세일 이벤트를 진행했는데, 갑작스럽게 몰린 트래픽을 감당 못한 서버가 다운되었다.
이로 인해 쇼핑 서비스와 관련 없는 수 많은 사용자가 불편을 겪었다.
이처럼, Monolithic Architecture 에서는 특정 서비스로 인해 문제가 생긴다면 서버 전체에 장애가 전파될 가능성이 높다. MSA 는 이러한 문제를 해결하기 위해 고안되었다.
MSA는 소프트웨어 시스템을 여러 개의 작은 서비스로 나누어 독립적으로 개발하고 배포하는 방식이다. MSA는 Monolithic Architecture 와 반대로 설계와 관리가 어렵다.
하지만 서비스간 장애 전파 가능성이 적고, 위 예시처럼 하나의 서비스에 트래픽이 몰리는 경우에 특정 서비스의 서버만 확장하여 유연하게 대처할 수 있다.
그 외에도 새로운 서비스를 확장하거나 서비스별로 다양한 개발 환경을 적용하는 등의 장점이 있다.
MSA의 개념과 장단점은 다음 링크에 좀 더 쉽게 설명되어 있다. (참고 링크)
MSA를 구현하기 위해 서비스를 분리하다 보면 공통적으로 필요한 코드가 생길 수 있다.
또한, 분리된 서비스를 서로 다른 프로젝트로 개발하려면 IDE를 여러개 켜놓고 정신없이 왔다갔다하며 개발해야 할 수도 있다.
공통적인 코드는 모듈을 통해 관리하고, 각 서비스를 하나의 프로젝트에서 관리하기 위해 멀티 모듈 프로젝트를 적용하기로 결정했다.
모듈과 서비스를 분리하기 전에 분리하는 기준을 정해야 한다.
잘 설계된 MSA를 위해서는 DDD와 같은 방법론에 의해 서비스를 분리하는 것이 좋겠지만, 이 프로젝트는 인프라 및 기술 학습에 더 큰 의미를 두었기 때문에 DDD를 적용하는 과정은 생략하였다.
대신 음악, 스트리밍, 라이브러리, 사용자 라는 최상위 도메인을 추출하였고 이를 바탕으로 다음과 같은 표를 통해 서비스를 분류하는 최소한의 과정을 거쳐보았다.
| 도메인 | 중요도 | 트래픽 | 액터 | 의존성 | 하위 도메인 |
|---|---|---|---|---|---|
| 음악 | 높음 | 높음 | 사용자, 관리자 | 사용자(인증) | 앨범, 아티스트 |
| 스트리밍 | 높음 | 높음 | 사용자 | 음악, 사용자(인증) | - |
| 사용자 | 높음 | 낮음 | 사용자 | - | 인증 |
| 라이브러리 | 중간 | 중간 | 사용자 | 사용자(식별), 음악 | 플레이리스트, 폴더 |
의존성 열에 괄호의 내용은 같은 최상위 도메인이더라도 다른 목적에 의해 사용된 경우 추가적인 정보를 적어주었다.
위 표를 바탕으로 서비스를 다음과 같이 나누려고 한다.
이번엔 분리한 서비스를 바탕으로 다음 두 글을 참고해서 나의 프로젝트를 어떻게 효과적으로 분리할지 고민하였다.
위 두 글을 참고하고, 현재 프로젝트 규모에 맞게 다음과 같이 모듈을 분리하려고 한다.
공통 인프라 모듈은 특정 인프라에 대한 일반적인 설정이나 객체를 정의하는 모듈이다.

예시로는 다음과 같은 모듈들이 있다.
도메인 모듈은 도메인, 레파지토리, 서비스 계층을 가진다.

music 도메인의 경우 사용자를 위한 서비스와 관리자를 위한 서비스의 공통 부분과 각자의 역할을 수행하는 모듈을 책임에 맞게 분리하였다.
현재는 MongoDB 도메인에 대해서만 모듈이 존재하지만, Redis 캐시와 같은 다른 인프라가 존재할 경우 인프라별로 모듈을 분리하고 각 모듈에서 인프라에 대한 설정을 관리할 수 있도록 설계하였다.
최종적으로 애플리케이션 모듈은 실제로 실행되는 모듈들이다. api와 관련된 모듈이나 지금은 없지만 batch 서버와 같은 모듈도 해당 계층에 포함될 수 있다.


현재 적용하려는 아키텍처, 기술 스택에 대한 기반지식이 굉장히 부족하여 '이런 구조로 적용이 가능할까?' 라는 생각에 다른 기술에 대해 검색하는 등 시간을 굉장히 많이 쏟았다. 또한 정답이 없는 설계에서 정답을 찾으려고 혼자서 고민의 굴레에서 벗어나지 못하고 헤메어 시간을 허비했다.
지금 설계한 아키텍처에 어떤 문제나 부족한 점이 있는지 정확히 알 수 없어, 기술을 적용하면서 보완해나가려고 한다.
멀티 모듈을 적용하는 방법에 대해서는 많은 레퍼런스가 있어 해당 과정에 대한 포스팅은 생략하도록 하겠다.