Conceptly
← 전체 목록
🧩

Modular Monolith

구조 패턴모듈 경계를 지키는 단일 배포 구조

Modular Monolith는 전체 애플리케이션을 하나의 배포 단위로 유지하되, 내부는 도메인별 모듈 경계로 강하게 분리하는 구조입니다. 겉으로는 Monolith이지만 안쪽에서는 각 모듈이 자기 공개 계약을 통해서만 협력하고, 다른 모듈의 내부 구현을 직접 건드리지 않도록 설계합니다. 즉, 분산 배포는 하지 않지만 경계 감각은 Microservices처럼 미리 훈련하는 방식입니다.

아키텍처 다이어그램

🔍 구조 다이어그램

점선 애니메이션은 데이터 또는 요청의 흐름 방향을 나타냅니다

왜 필요한가요?

전통적인 Monolith는 시작은 빠르지만 시간이 지나면 모듈 경계가 흐려지기 쉽습니다. 주문 코드가 결제 테이블을 직접 읽고, 회원 모듈이 다른 모듈의 내부 클래스를 호출하면서 결합도가 빠르게 올라갑니다. 그렇다고 곧바로 Microservices로 가면 네트워크, 배포, 관측, 데이터 정합성 문제를 한꺼번에 떠안게 됩니다. 내부 결합은 줄여야 하지만 분산 시스템 비용은 아직 감당하기 어려운 시점이 바로 Modular Monolith가 필요한 지점입니다.

왜 이런 방식이 등장했나요?

마이크로서비스 유행 초기에 많은 팀이 배포 단위부터 쪼갔지만, 도메인 경계가 충분히 다듬어지지 않은 상태에서 나뉜 서비스는 오히려 호출만 늘고 책임은 더 흐려졌습니다. 반대로 그냥 Monolith에 머무르면 경계 실험을 할 기회가 없어서 나중에 쪼갤 근거가 약해집니다. 그래서 하나의 런타임 안에서 먼저 모듈 경계를 고정하고, 진짜 분산이 필요한지 나중에 판단하자는 접근이 실무에서 다시 주목받게 됐습니다.

내부적으로 어떻게 동작하나요?

구조의 핵심은 모듈마다 공개 인터페이스와 내부 구현을 분리하는 것입니다. 주문 모듈은 주문 생성과 조회에 대한 계약만 외부에 열고, 결제 모듈은 그 계약을 통해서만 협력합니다. 런타임과 배포는 하나지만, 코드 의존성은 모듈 단위로 제한합니다. 데이터베이스를 공유하더라도 테이블 소유권을 모듈 단위로 나누고, 직접 조인보다 모듈 API 호출이나 내부 이벤트를 통해 흐름을 연결하는 편이 경계를 지키는 데 유리합니다.

경계와 구분

Monolith와의 차이는 배포 단위가 아니라 경계의 강도에 있습니다. 둘 다 하나의 프로세스로 움직이지만, Modular Monolith는 모듈 간 내부 침범을 설계상 금지합니다. Microservices와의 차이는 경계를 넘는 비용입니다. Modular Monolith에서는 모듈 호출이 프로세스 내부에서 끝나므로 네트워크 비용과 분산 장애를 피할 수 있습니다. 대신 독립 확장과 독립 배포가 절실한 환경에서는 결국 배포 경계 분리가 필요합니다.

언제 쓰나요?

팀은 아직 작지만 도메인은 점점 복잡해지고, 나중에 서비스 분리를 할 가능성도 높은 제품에서 유용합니다. 특히 주문, 결제, 재고처럼 책임 단위는 뚜렷한데 운영 복잡도를 크게 늘리고 싶지 않을 때 적합합니다. 이 구조는 마이크로서비스로 가기 위한 임시 단계일 수도 있고, 충분히 오랫동안 유지할 최종 형태일 수도 있습니다. 핵심은 모듈 경계가 실제 코드 의존성에서 지켜지느냐입니다.

서비스 분리 전 단계소규모 팀 제품레거시 정리도메인별 소유권 정리