모듈러 모노리스에서 도메인 간 통신을 어떻게 할까?
모놀리식은 처음엔 정말 편하다.
빠르게 만들 수 있고, 한 번에 다 돌아간다.
그러나 규모가 점점커지면 도메인간 의존성이 얽히기 시작한다.
이문제를 해결하고 나온 마이크로 서비스 아키텍처.
2010년 후반부터 광풍이 일기 시작했고, 대표적으로 Netflix 가 자신들의 아키텍처를 공개하면서 많은 기업들이 따라하기 시작했다.
Netflix OSS 기반 MSA 는 구조적으로는 아름다웠다.
도메인 간 경계를 세부적으로 쪼개고, 도메인간 통신은 Client Side Loadbalancing 을 통해 제어했다. (꼭 Netflix OSS 기반, Client Side LB 가 아니라도 대게 마찬가지다.)
또 동적 노드 추가로 언제든 트래픽이 몰리는 도메인을 쉽게 증설할수 있었다.
그러나...
그 철학으로 따라가다 보면, 서비스를 운영하기 위해 너무나 많은 도메인, 노드를 운영해야 했다.
트래픽이 거의 없는 도메인 및 노드도 최소한의 자원은 할당해야 했으며, 당연히 git 으로 관리해야할 프로젝트도 그만큼 늘어났다.
아름다웠지만, 너무 비싼 녀석이었다... Netflix 만큼 모든 도메인이 많은 트래픽이 많지도 않았다.
또 나의 경우에는 서비스 규모에 비해 복잡한 비즈니스를 구현했어야 하는데, 그러다 보니 100개가 넘는 도메인을 각각 개발하고 관리해야 했다. 글로벌 기업수준도 아닌데 이건...
이러한 문제점을 보완하기 위해 최근 각광받는 Mono Repo, 그리고 Modular Monolith,
이 글은 모듈러 모노리스에 대한 이야기를 해보고자 한다.
(참고로 나는 Mono Repo 스타일은 별로 좋아하지 않는다. )
도메인이 늘어나기 시작하면
자연스럽게 이런 코드가 생긴다.
- Order가 Payment를 직접 호출하고
- Payment가 다시 Inventory를 건드리고
- 어느 순간 서로가 서로를 참조한다
처음엔 단순한 “함수 호출”이었는데,
나중엔 얽히고설킨 의존성 덩어리가 된다.
그리고 이 시점에서 대부분 이렇게 생각한다.
“헥사고날 아키텍처 쓰면 해결되는 거 아니야?”
헥사고날 아키텍처로 도메인을 서로 외부 경계로 바라본다면
Port / Adapter 구조를 도입하면
도메인 간 통신을 마치 외부 시스템처럼 다룰 수 있다.
예를 들면:
- Order → PaymentPort (인터페이스)
- PaymentAdapter → 실제 구현
이렇게 하면 나중에
HTTP, gRPC, 메시지 기반으로 바꾸기도 쉬워진다.
딱 봐도 “MSA 전환 준비 완료” 느낌이다.
근데 여기서 함정이 있다.
문제는 기술이 아니라 구조다
Port/Adapter를 쓰면 미래 대비가 된다고 생각한다
하지만 좀더 중요한 요소가 있다.
미래에 시스템을 쪼갤 수 있느냐는
Port가 아니라 “도메인 구조”가 결정한다.
진짜 중요한 4가지
1. 의존 방향은 무조건 단방향
Order → Payment (O)
Payment → Order (X)
순환 의존이 생기는 순간
그 도메인은 절대 분리할 수 없다.
2. 상태 공유하지 않기
- 같은 DB 테이블을 같이 쓰거나
- 서로 join해서 데이터 가져오기 시작하면
이미 한 몸이다.
나중에 분리? 거의 불가능하다.
3. 느슨한 결합은 이벤트로
OrderCreated → Payment 처리
이벤트 기반으로 바꾸는 순간
도메인 간 결합도가 확 낮아진다.
4. 진짜 분리될 도메인만 Port/Adapter
모든 걸 Port로 감싸는 건 오버엔지니어링이다. 게다가 CRQS 개념 분리까지 생각하면 Port, Adapter 천국이 될 수 있다.
대신 이렇게 생각하자.
“이 도메인은 나중에 진짜 따로 나갈 가능성이 높은가?”
- 결제
- 인증
- 알림
이런 영역만 Port/Adapter로 감싸면 된다.
그래서 결론은
모듈러 모놀리스에서 중요한 건
“지금부터 분산 시스템처럼 만드는 것”이 아니다.
나중에 분리할 수 있는 구조를 만드는 것
정리하면 딱 이거다.
- 도메인 간 통신은 단순하게 Service 호출
- 느슨한 결합은 이벤트로 해결
- 의존성은 단방향 유지
- 상태는 절대 공유하지 않기
- 정말 필요한 곳만 Port/Adapter 적용
한 줄 정리
미래를 대비한다는 건 기술을 추가하는 게 아니라,
구조를 망치지 않는 것이다
모놀리식 아키텍처, 모듈러 모노리스, 헥사고날 아키텍처, Port Adapter, 도메인 설계, MSA 전환, 이벤트 기반 아키텍처