2025. 2. 26. 12:39ㆍSpring Microservice
마이크로서비스에서 가장 큰 도전 과제 중 하나는 개별 서비스의 경계를 정의하는 것입니다. 일반적으로 "하나의 서비스는 하나의 일을 수행해야 한다" 는 원칙이 있지만, 이를 실무에서 적용하려면 신중한 고민이 필요합니다.
정확한 설계를 보장하는 기계적인 방법은 존재하지 않습니다. 올바른 서비스를 설계하려면 다음과 같은 요소들을 깊이 고려해야 합니다.
- 비즈니스 도메인
- 요구사항
- 아키텍처 특성(비기능적 요구사항, Non-Functional Requirements)
- 시스템 목표
이러한 요소를 제대로 고려하지 않으면, 다음과 같은 문제가 발생할 수 있습니다.
- 서비스 간 숨겨진 의존성
- 서비스 간 강한 결합(Tight Coupling)
- 잘못 설계된 인터페이스
이 글에서는 도메인 중심(Domain-Driven) 접근 방식을 통해 마이크로서비스를 설계하는 방법을 설명합니다.
또한, 마이크로서비스 경계 평가(Evaluating Service Boundaries)는 지속적인 과정입니다.
- 워크로드가 발전함에 따라 기존 경계를 재정의해야 하는 경우가 발생할 수 있습니다.
- 이를 수용하기 위해 추가적인 애플리케이션 개발이 필요할 수도 있습니다.
이 글에서는 드론 배송 서비스(Drone Delivery Service) 를 예제로 활용하여 마이크로서비스 설계를 설명합니다.
소개
마이크로서비스는 데이터 액세스 또는 메시징과 같은 수직적 계층이 아니라 비즈니스 기능을 중심으로 설계해야 합니다. 또한, 느슨한 결합(loose coupling)과 높은 기능적 응집도(high functional cohesion) 를 가져야 합니다.
- 느슨한 결합: 하나의 서비스를 변경할 때 다른 서비스도 동시에 업데이트해야 하는 경우가 없어야 합니다.
- 높은 응집도: 하나의 마이크로서비스는 명확하게 정의된 단일 목적을 가져야 합니다.
예를 들어, 사용자 계정을 관리하거나 배송 이력을 추적하는 역할을 수행할 수 있습니다.
마이크로서비스는 도메인 지식(domain knowledge) 을 캡슐화하고, 이를 클라이언트로부터 추상화해야 합니다.
예를 들어, 클라이언트가 드론을 예약할 때, 예약 알고리즘의 세부 사항이나 드론 운영 방식에 대해 알 필요가 없어야 합니다.
또한, 각 마이크로서비스는 전체 시스템이 아닌, 해당 도메인의 요구사항에 맞는 아키텍처 특성(Architecture Characteristics) 을 정의해야 합니다.
- 예시:
- 고객이 직접 사용하는 서비스(Customer-Facing Microservice): 성능, 가용성, 장애 허용성, 보안, 테스트 용이성, 민첩성이 중요
- 백엔드 서비스(Backend Microservice): 장애 허용성과 보안만 중요한 경우도 있음
그러나 마이크로서비스 간 동기식 통신(synchronous communication) 이 많아지면, 서비스 간의 의존성이 높아지면서 동일한 아키텍처 특성을 공유해야 하는 문제가 발생할 수 있습니다.
도메인 주도 설계(DDD, Domain-Driven Design) 는 이러한 문제를 해결하기 위한 프레임워크를 제공합니다.
DDD는 두 가지 단계로 구분됩니다.
- 전략적 DDD(Strategic DDD): 시스템의 대규모 구조를 정의하는 단계
- 아키텍처가 비즈니스 기능 중심으로 설계될 수 있도록 보장
- 전술적 DDD(Tactical DDD): 도메인 모델을 설계하는 데 사용할 수 있는 패턴 제공
- 패턴 예시: 엔터티(Entity), 애그리게이트(Aggregate), 도메인 서비스(Domain Service)
이러한 전술적 패턴을 활용하면, 느슨한 결합과 높은 응집도를 갖춘 마이크로서비스를 설계할 수 있습니다.

이 글과 다음 글에서는 드론 배송 애플리케이션(Drone Delivery Application)에 적용하여 다음 단계를 따라가겠습니다.
- 비즈니스 도메인 분석
- 애플리케이션의 기능적 요구사항을 이해하기 위해 비즈니스 도메인을 분석합니다.
- 이 단계의 결과물은 도메인의 비공식적인 설명이며, 이를 보다 공식적인 도메인 모델로 정제할 수 있습니다.
- 도메인의 경계(context) 정의
- 각 경계 컨텍스트(Bounded Context) 를 정의합니다.
- 각 컨텍스트에는 특정 하위 도메인을 나타내는 도메인 모델이 포함됩니다.
- 전술적 DDD 패턴 적용
- 각 경계 컨텍스트 내에서 전술적 DDD(Tactical DDD) 패턴 을 적용합니다.
- 이를 통해 엔터티(Entity), 애그리게이트(Aggregate), 도메인 서비스(Domain Service) 등을 정의합니다.
- 마이크로서비스 식별
- 이전 단계의 결과를 바탕으로 애플리케이션 내에서 마이크로서비스를 식별합니다.
이번 글에서는 DDD와 관련된 첫 세 가지 단계를 다룹니다.
다음 글에서는 마이크로서비스를 식별하는 과정을 설명할 것입니다.
그러나, DDD는 반복적이고 지속적인 과정이라는 점을 기억하는 것이 중요합니다.
마이크로서비스의 경계는 고정된 것이 아니며, 애플리케이션이 발전하면서 기존 서비스를 여러 개의 작은 서비스로 분리해야 할 수도 있습니다.
Note: 이 글에서는 완전하고 포괄적인 도메인 분석을 다루지 않습니다.주요 개념을 설명하기 위해 예제를 간략하게 구성하였습니다. DDD에 대한 더 깊은 이해를 위해서는 Eric Evans의 『Domain-Driven Design』 을 참고하시길 바랍니다.이 책은 DDD 개념을 처음 소개한 저서입니다. 또한, Vaughn Vernon의 『Implementing Domain-Driven Design』 도 유용한 참고 자료가 될 수 있습니다.
시나리오: 드론 배송 서비스
Fabrikam, Inc.은 드론 배송 서비스를 시작하려고 합니다.
이 회사는 드론 항공기(Drone Aircraft) 운영을 관리합니다.
- 기업들이 이 서비스에 등록하면,
- 사용자는 드론을 요청하여 상품 픽업 및 배송을 할 수 있습니다.
고객이 픽업을 예약하면,
- 백엔드 시스템이 드론을 배정하고,
- 고객에게 예상 배송 시간(ETA, Estimated Time of Arrival) 을 알립니다.
배송이 진행되는 동안,
- 고객은 드론의 실시간 위치를 추적하고,
- 계속 업데이트되는 ETA 정보를 확인할 수 있습니다.
이 시나리오는 상당히 복잡한 도메인을 포함합니다.
비즈니스에서 고려해야 할 주요 요소는 다음과 같습니다.
- 드론 스케줄링
- 패키지 추적
- 사용자 계정 관리
- 과거 데이터 저장 및 분석
또한, Fabrikam은 빠르게 시장에 진입하고,
- 이후 빠르게 반복 개발(Iterate Quickly) 하면서
- 새로운 기능과 역량을 지속적으로 추가하려고 합니다.
이 애플리케이션은 클라우드 규모(Cloud Scale) 로 운영되어야 하며,
- 높은 서비스 수준 목표(SLO, Service Level Objective) 를 충족해야 합니다.
- 시스템의 각 부분마다 데이터 저장 및 조회 방식이 다를 가능성이 높습니다.
이러한 모든 고려 사항을 바탕으로,
Fabrikam은 드론 배송 애플리케이션을 마이크로서비스 아키텍처로 설계하기로 결정했습니다.
도메인 분석
DDD 접근 방식을 사용하면 각 마이크로서비스가 특정 비즈니스 요구사항에 자연스럽게 맞춰지도록 설계할 수 있습니다.
또한, 조직 구조나 기술 선택이 설계를 좌우하는 문제를 피하는 데 도움이 됩니다.
코드를 작성하기 전에, 먼저 개발할 시스템을 전체적으로 조망할 필요가 있습니다.
DDD는 비즈니스 도메인을 모델링하고, 도메인 모델을 생성하는 것부터 시작합니다.
- 도메인 모델(Domain Model) 은 비즈니스 도메인을 추상적으로 표현한 모델입니다.
- 이는 도메인 지식(Domain Knowledge) 을 정리하고 체계화하며,
- 개발자와 도메인 전문가 간의 공통 언어(Ubiquitous Language) 를 제공합니다.
1. 비즈니스 기능과 연결 관계 파악
먼저, 모든 비즈니스 기능을 매핑하고, 이들의 관계를 분석합니다.
- 이 과정은 도메인 전문가, 소프트웨어 아키텍트, 기타 이해관계자 가 함께 협력해야 합니다.
- 특정한 형식을 따를 필요는 없으며,
- 다이어그램을 그리거나 화이트보드에 개략적으로 정리해도 충분합니다.
2. 서브도메인(Subdomains) 식별
다이어그램을 채워가면서, 별도의 서브도메인을 식별할 수 있습니다.
- 서로 밀접하게 관련된 기능은 무엇인가?
- 비즈니스의 핵심(Core) 기능과 보조(Ancillary) 기능을 어떻게 구분할 것인가?
- 의존성 그래프(Dependency Graph)는 어떻게 형성되는가?
이 초기 단계에서는 기술 스택이나 구현 방식은 고려하지 않습니다.
다만, 애플리케이션이 외부 시스템(CRM, 결제 처리, 청구 시스템 등) 과 통합이 필요한 부분은 미리 확인해 두어야 합니다.
예제: 드론 배송 애플리케이션
초기 도메인 분석을 거친 후, Fabrikam 팀은
드론 배송 도메인을 나타내는 대략적인 스케치(초기 설계) 를 작성했습니다.

배송(Shipping)이 도메인의 중심
배송(Shipping)은 비즈니스의 핵심 기능이므로, 다이어그램의 중앙에 배치되었습니다.
다이어그램에 포함된 다른 모든 요소들은 배송 기능을 지원하기 위해 존재합니다.
핵심 기능(Core Business Functions)
- 드론 관리(Drone Management) 역시 비즈니스의 핵심 기능입니다.
- 드론 수리(Drone Repair) 및
- 예측 분석(Predictive Analysis) 을 활용하여
- 드론이 언제 정비 및 유지보수가 필요한지 예측하는 기능이 포함됩니다.
- ETA 분석(ETA Analysis)
- 픽업 및 배송 예상 시간(Estimated Time of Arrival, ETA) 을 제공하는 기능입니다.
- 제3자 운송(Third-Party Transportation)
- 드론만으로 배송이 불가능한 경우,
- 대체 운송 수단을 예약 할 수 있도록 지원합니다.
- 드론만으로 배송이 불가능한 경우,
미래 확장 가능 기능(Potential Future Expansions)
- 드론 공유(Drone Sharing)
- 코어 비즈니스의 확장 가능성 중 하나입니다.
- 특정 시간대에 드론이 유휴 상태(Idle)로 남을 경우,
- 대여(Rental) 서비스 를 제공하는 기능을 추가할 수도 있습니다.
- 그러나 초기 출시 버전에는 포함되지 않습니다.
- 영상 감시(Video Surveillance)
- 향후 비즈니스 확장 가능성 중 하나입니다.
- 추후 보안 감시 등의 기능을 추가할 가능성이 있습니다.
코어 비즈니스를 지원하는 서브도메인(Supporting Subdomains)
- 사용자 계정(User Accounts)
- 청구/인보이스(Invoicing)
- 고객 지원 센터(Call Center)
이들은 비즈니스의 핵심 기능을 지원하는 서브도메인 입니다.
기술 및 구현 관련 고려 사항 없음
현재 단계에서는 아직 구현 방식이나 기술 스택을 결정하지 않았습니다.
- 일부 서브시스템은 외부 소프트웨어 시스템 또는 서드파티 서비스 를 활용할 수도 있습니다.
- 그러나 애플리케이션이 이러한 시스템 및 서비스와 상호작용 해야 하기 때문에,
도메인 모델에 포함하는 것이 중요합니다.
애플리케이션이 외부 시스템에 의존하는 경우 외부 시스템의 데이터 스키마 또는 API가 애플리케이션으로 유출되어 궁극적으로 아키텍처 설계를 손상시킬 위험이 있습니다. 이는 특히 최신 모범 사례를 따르지 않고 복잡한 데이터 스키마나 오래된 API를 사용할 수 있는 레거시 시스템에서 더욱 그렇습니다. 이 경우 이러한 외부 시스템과 애플리케이션 간에 잘 정의된 경계를 두는 것이 중요합니다. 이 목적을 위해 Strangler Fig 패턴이나 Anti-Corruption Layer 패턴을 사용하는 것을 고려하세요.
경계 컨텍스트(Bounded Contexts) 정의
도메인 모델에는 현실 세계의 객체(예: 사용자, 드론, 패키지 등)가 포함됩니다.
그러나 시스템의 모든 부분이 동일한 방식으로 이러한 객체를 표현할 필요는 없습니다.
예를 들어:
- 드론 수리(Drone Repair) 및 예측 분석(Predictive Analysis) 서브시스템
- 드론의 정비 이력, 주행 거리, 연식, 모델 번호, 성능 특성 등
- 여러 물리적 속성을 포함해야 합니다.
- 배송 스케줄링(Scheduling) 서브시스템
- 드론의 정비 이력이나 성능 특성은 필요하지 않습니다.
- 드론이 사용 가능한지 여부, ETA(예상 도착 시간) 만 중요합니다.
만약 이 두 서브시스템을 위한 단일 모델을 만든다면
- 모델이 불필요하게 복잡해지고
- 시간이 지나면서 각 서브시스템을 담당하는 팀 간 충돌이 발생할 가능성이 높습니다.
- (각 팀이 자신의 요구사항을 모델에 반영하려 하기 때문)
따라서, 동일한 현실 세계의 개체(예: 드론)를 표현하더라도
- 서로 다른 맥락(Context)에서 별도의 모델을 설계하는 것이 더 적절합니다.
- 각 모델은 해당 컨텍스트에서 필요한 속성만 포함해야 합니다.
이때, DDD의 핵심 개념인 "경계 컨텍스트(Bounded Context)" 가 적용됩니다.
- 경계 컨텍스트란?
- 특정 도메인 모델이 적용되는 경계(Boundary) 영역을 의미합니다.
이전 다이어그램을 다시 살펴보면,
- 기능을 그룹화하여, 여러 기능이 동일한 도메인 모델을 공유하는지 여부를 결정할 수 있습니다.

경계 컨텍스트(Bounded Contexts) 간의 상호작용
경계 컨텍스트는 반드시 서로 완전히 분리된 상태(Isolated) 일 필요는 없습니다.
위 다이어그램에서
- 실선(Solid Lines) 으로 연결된 부분은
- 두 개의 경계 컨텍스트가 상호작용(Interact)하는 지점 을 나타냅니다.
예를 들어:
- 배송(Shipping) 컨텍스트는
- 사용자 계정(User Accounts) 컨텍스트를 통해 고객 정보를 조회하고,
- 드론 관리(Drone Management) 컨텍스트를 통해 배송할 드론을 예약 합니다.
경계 컨텍스트 간 상호작용을 유지하는 패턴
Eric Evans의 『Domain-Driven Design』 에서는
도메인 모델의 무결성(Integrity)을 유지하면서 다른 경계 컨텍스트와 상호작용하는 방법을 설명하는 여러 패턴을 소개합니다.
마이크로서비스 아키텍처의 핵심 원칙 중 하나는
- 각 서비스가 명확하게 정의된 API를 통해 통신하는 것 입니다.
이 원칙은 Evans가 제안한 두 가지 패턴 과 연관됩니다.
- Open Host Service 패턴
- 서브시스템이 공식적인 프로토콜(API) 을 정의하여
- 다른 서브시스템이 이를 통해 통신할 수 있도록 합니다.
- Published Language 패턴
- API를 공개된 표준 형식 으로 문서화하여
- 다른 팀에서 해당 API를 사용하여 클라이언트를 개발할 수 있도록 합니다.
마이크로서비스 API 설계와 OpenAPI Specification
"Designing APIs for microservices" 글에서는
- OpenAPI Specification (구 Swagger) 을 사용하여
- REST API를 기술 독립적인 형식(Language-Agnostic)으로 정의하는 방법을 설명합니다.
- JSON 또는 YAML 형식으로 API 문서를 작성 할 수 있습니다.
이제부터는 "배송(Shipping) 경계 컨텍스트" 에 초점을 맞춰 설명하겠습니다.
다음 단계
도메인 분석(Domain Analysis)을 완료한 후,
다음 단계는 전술적 DDD(Tactical DDD) 를 적용하여
도메인 모델을 보다 정교하게 정의하는 것입니다.
출처 : https://learn.microsoft.com/en-us/azure/architecture/microservices/model/domain-analysis
'Spring Microservice' 카테고리의 다른 글
Identify microservice boundaries (0) | 2025.02.26 |
---|---|
Using tactical DDD to design microservices (0) | 2025.02.26 |
Microservices architecture design (0) | 2025.02.26 |
Promethous/Grafana (0) | 2024.12.22 |
Spring Cloud Gateway에서 CORS(Cross-Origin Resource Sharing) 지원 (0) | 2024.12.15 |