02 MSA 도메인 설계
02 MSA 도메인 설계
1. Note
- MSA를 진행할 때 임의로 경계를 나누고 작업하다 보면
- 여러 가지 상황이나 케이스가 발생할 우려가 있음
- 따라서 DDD로 진행하면, 기존에 존재하던 방법론이고
- 다양한 규칙과 정형화된 패턴들이 정돈되어 있어서
- 이를 기준으로 소통하고 작업하면 편함
- DDD는 방법론(★)
- 소스를 만들 때 정답이 있는 개념이 아님
- 어떻게 설계하고 만들어 나가야 하는지에 대한 관점
2. DDD
1. DDD
- 기술(프레임워크, DB 구조) 중심이 아닌, 소프트웨어가 해결하고자 하는 비즈니스 문제 영역(도메인)에 집중하여 설계하는 방법론
도메인 이해 -> 전략적 설계 -> 전술적 설계 -> 구현흐름으로 계속 반복적으로 이어나가는 과정
2. 도메인 (Domain)
- 소프트웨어로 해결하고자 하는 비즈니스 활동의 전체 영역
- 쿠팡이나 배달의민족과 같은 ‘이커머스/배달 비즈니스 전체’
3. 서브도메인 (Subdomain)
- 핵심 서브도메인(Core Domain)
- 비즈니스의 차별점이자 가장 중요한 영역
- 배달 앱의 주문/매칭 로직 등
- 지원 서브도메인(Supporting Domain)
- 핵심을 돕는 부가 기능
- 리뷰 작성, 게시판 관리
- 일반 서브도메인(Generic Domain)
- 필수적이지만 외부 솔루션 대체가 가능한 영역
- 인증/결제, 이메일 발송
4. 모델 (Model)
- 비즈니스 규칙을 해결하기 위해 개념적으로 추상화한 구조
- 도메인 문제 해결 중심 구조
- 언어 진영마다 표현 단위가 다름
5. 유비쿼터스 언어 (Ubiquitous Language)
- 기획자, 도메인 전문가, 개발자가 프로젝트 전반에서 공통으로 사용하는 표준화된 업무 용어
- 현업은 ‘회원’, 개발자는 ‘User’, DB에는 ‘Member’로 쓰던 혼란을 막는 하나의 합의된 용어
- 각 부서 및 파트의 컨벤션에 따름.
3. 설계 전략
1. 전략적 설계 (Strategic Design)
1. 전략적 설계 개념
- 도메인을 “어떻게 나눌 것인가”에 대한 상위 설계
- 큰 덩어리를 나누는 단계 (각기 컨텍스트는 뭘 하는가?)
- 흐름
1 2 3 4 5 6 7 8 9 10 11 12 13 14
[ 전체 비즈니스 도메인 ] | ----------------------------------- | | | [ 주문 ] [ 결제 ] [ 회원 ] | | | | | | (서비스 1) (서비스 2) (서비스 3) | | | ----------------------------------- | Context Mapping (관계) 주문 → 결제 요청 결제 → 주문 상태 변경
1. Bounded Context
- 하나의 의미와 모델이 유지되는 경계
- 같은 단어라도 컨텍스트에 따라 의미가 달라지지 않도록 분리
- MSA에서는 하나의 마이크로서비스 경계가 됨 ( DDD의 핵심이자 MSA 설계 기준)
2. Context Mapping
- Bounded Context들 간의 관계 정의
- 서비스 간 의존 구조를 명확히 표현
- 예: 주문 서비스 → 결제 서비스 호출 관계
3. 서브도메인 기반 분리 전략
- 도메인을 역할 기준으로 분해
- Core / Supporting / Generic
- 중요한 영역부터 서비스로 분리하는 기준 제공
2. 전술적 설계 (Tactical Design)
2. 전술적 설계 개념
- 실제 코드 레벨에서 도메인을 어떻게 구현할 것인가
- 서비스 하나 안을 설계하는 단계
- 흐름
1 2 3 4 5 6 7 8 9 10 11 12 13
[ Order Service 내부 ] Aggregate (Order Aggregate) | -------------------------------- | | | Entity Value Object Domain Service Order Money PriceCalculator OrderItem Address | Repository (DB 접근 담당)
1. Aggregate
- 여러 객체(Entity/VO)를 하나의 트랜잭션 단위로 묶은 구조
- 일관성을 보장하는 경계 (트랜잭션 최소 단위)
- Aggregate Root를 통해서만 내부 객체 접근
2. Entity
- 고유 ID를 가지는 객체
- 상태가 변경될 수 있음
- 예: User, Order
3. Value Object
- 값 자체가 의미를 가지는 객체
- 불변(Immutable)
- 예: Address, Money
4. Repository
- 데이터 저장/조회 추상화 계층
- DB 접근을 캡슐화
5. Domain Service
- 특정 Entity나 VO에 속하지 않는 도메인 로직 처리
- 여러 객체를 조합한 비즈니스 로직 담당
- 할인 계산(order, product, user 등의 결합)
4. MSA에 DDD 이점
1. 서비스 간 경계(Bounded Context)의 명확화
- Bounded Context = MSA 서비스 경계
- 비즈니스 기준으로 완전히 분리된 영역 정의
- 마이크로서비스 배포 단위와 일치
2.도메인 지식과 엔티티 구조의 일치
- DB 중심 설계 → 도메인 중심 설계로 전환
- Entity / Aggregate가 비즈니스 개념과 직접 매핑
- 변경이 코드 구조에 자연스럽게 반영됨
3. 데이터 독립성과 서비스 자율성 확보
- MSA에서는 서비스마다 DB를 분리해야 함 (Database-per-Service)
- 이때 단순히 “기능 기준”으로 나누면 경계가 쉽게 깨짐
- DDD의 Bounded Context는 “데이터 + 로직 + 의미”를 함께 묶는 기준 제공
4. 팀 단위 개발과 조직 구조와의 정합성
- MSA는 기술 구조이면서 동시에 조직 구조와 강하게 연결됨 (Conway’s Law)
- DDD의 Bounded Context는 팀 단위 책임 영역과 자연스럽게 일치
5. 서비스 간 결합도 감소 (Loose Coupling)
- DDD 없이 설계하면 서비스가 DB나 내부 로직에 강하게 의존하는 구조가 되기 쉬움
- Bounded Context를 기준으로 나누면
- 내부 모델은 완전히 독립
- 외부는 API / 이벤트로만 통신
6. 도메인 복잡도 증가에 대한 대응
- 단순 CRUD 구조에서는 DDD 필요성이 낮음
- 하지만 실제 MSA는 다음 특징이 있음:
- 복잡한 비즈니스 규칙
- 상태 변화가 많은 도메인
- 서비스 간 연쇄 흐름
7. Database-per-Service 구조와 연결
- 각 Bounded Context(=서비스)는 자신만의 데이터베이스를 독립적으로 가짐
- 다른 서비스의 DB에 직접 접근하지 않고 API 또는 이벤트로만 데이터 교환
- 서비스 단위로 데이터 소유권을 분리하여 독립성 확보
- 결과적으로 서비스 간 결합도를 낮추고, 장애 및 변경 영향 범위를 최소화
5. DDD/TDD/BDD
| 구분 | DDD | TDD | BDD |
|---|---|---|---|
| 풀네임 | Domain-Driven Design | Test-Driven Development | Behavior-Driven Development |
| 성격 | 설계 방법론 | 개발 방법론 | 테스트 + 요구사항 방법론 |
| 중심 | 비즈니스 도메인 | 테스트 코드 | 사용자 행동(시나리오) |
| 목적 | 복잡한 도메인 구조화 | 코드 안정성 / 설계 개선 | 요구사항을 테스트로 표현 |
| 기준 | 도메인 / 모델 | 테스트 케이스 | Given-When-Then |
| 산출물 | 도메인 모델, 아키텍처 | 테스트 코드 | 시나리오 기반 테스트 |
| MSA 관계 | 서비스 경계 기준 제공 | 서비스 내부 품질 | API/기능 검증에 활용 |
This post is licensed under CC BY 4.0 by the author.