2025. 2. 26. 22:35ㆍSpring Microservice
마이크로서비스의 적절한 크기는 무엇일까요? "너무 크지도 않고 너무 작지도 않게"라는 말을 자주 듣는데, 물론 맞는 말이지만 실제로는 별로 도움이 되지 않습니다. 하지만 신중하게 설계된 도메인 모델에서 시작하면 마이크로서비스에 대해 훨씬 쉽게 추론할 수 있습니다.
이 글에서는 드론 배송 서비스를 계속 사용되는 예시로 활용합니다. 시나리오 및 해당 참조 구현에 대해 자세히 알아보려면 다음 내용을 읽어보세요.
From domain model to microservices
이전 단계 요약
이전 글에서는 드론 배송(Drone Delivery) 애플리케이션의 경계 컨텍스트(Bounded Contexts)를 정의 했습니다.
그 후, 배송(Shipping) 경계 컨텍스트를 자세히 분석하여 엔터티(Entity), 애그리게이트(Aggregate), 도메인 서비스(Domain Service)를 식별 했습니다.
도메인 모델에서 애플리케이션 설계로 전환
이제 도메인 모델을 기반으로 마이크로서비스를 도출 할 준비가 되었습니다.
다음은 도메인 모델에서 마이크로서비스를 설계하는 방법 입니다.
1️⃣ 경계 컨텍스트에서 시작
- 일반적으로 하나의 마이크로서비스는 하나의 경계 컨텍스트를 초과해서는 안 됩니다.
- 경계 컨텍스트는 특정 도메인 모델의 경계를 정의 합니다.
- 만약 하나의 마이크로서비스가 여러 개의 도메인 모델을 혼합하고 있다면,
- 도메인 분석을 다시 검토해야 할 가능성이 높습니다.
2️⃣ 애그리게이트(Aggregates) 분석
애그리게이트는 마이크로서비스 후보 로 적절한 경우가 많습니다.
애그리게이트는 다음과 같은 마이크로서비스의 특성과 유사한 특징을 가집니다.
- 비즈니스 요구사항(Business Requirements)에 의해 정의됨
- 데이터 액세스(Data Access)나 메시징(Messaging)과 같은 기술적 요소 가 아니라
- 비즈니스 기능 중심으로 설계 되어야 합니다.
- 높은 기능적 응집도(High Functional Cohesion) 를 가짐
- 데이터 영속성(Persistence)의 경계를 형성
- 느슨한 결합(Loose Coupling)이 가능해야 함
3️⃣ 도메인 서비스(Domain Services) 분석
- 도메인 서비스는 여러 애그리게이트에 걸쳐 동작하는 무상태(Stateless) 연산 을 처리합니다.
- 여러 개의 마이크로서비스를 조정하는 워크플로우(Workflow) 역할 을 할 수 있습니다.
- 예를 들어, 드론 배송 애플리케이션에서 "Scheduler" 서비스 가 이에 해당합니다.
4️⃣ 비기능적 요구사항(Non-Functional Requirements) 고려
- 팀 규모(Team Size), 데이터 유형(Data Types), 기술 스택(Technologies), 확장성(Scalability), 가용성(Availability), 보안(Security) 등 고려
- 이러한 요인들에 따라
- 마이크로서비스를 더 작은 서비스로 분할 하거나
- 여러 개의 마이크로서비스를 통합 해야 할 수도 있음
마이크로서비스 설계 검증 기준
아래 기준을 통해 설계한 마이크로서비스가 적절한지 검토 합니다.
✔ 각 서비스는 단일 책임(Single Responsibility)을 가져야 합니다.
✔ 서비스 간 과도한 통신(Overly Chatty Calls)이 없어야 합니다.
- 기능을 두 개의 서비스로 분리한 결과 과도한 호출이 발생한다면,
- 이는 두 기능이 같은 서비스 내에 있어야 한다는 신호 일 수 있습니다.
✔ 각 서비스는 소규모 팀이 독립적으로 개발 가능할 정도로 작아야 합니다.
✔ 두 개 이상의 서비스가 동시에 배포되어야 하는 "동시 배포(Deployment Lock-step)" 의존성이 없어야 합니다.
- 즉, 어떤 서비스든 독립적으로 배포할 수 있어야 합니다.
✔ 서비스 간 결합이 느슨해야 하며, 독립적으로 발전할 수 있어야 합니다.
✔ 데이터 일관성(Data Consistency) 및 무결성(Integrity) 문제를 초래하지 않는지 확인해야 합니다.
- 일부 기능은 데이터 일관성을 유지하기 위해 단일 마이크로서비스 내에서 처리 하는 것이 더 적절할 수도 있음.
- 그러나 분산 시스템에서는 "강한 일관성(Strong Consistency)" 이 항상 필요하지 않을 수 있음.
- "최종적 일관성(Eventual Consistency)" 을 관리하는 전략을 고려 해야 하며,
- 마이크로서비스 분리의 장점이 데이터 일관성 관리의 복잡성을 초과하는지 평가해야 함.
마지막으로, 실용적 접근(Pragmatic Approach) 유지
- 도메인 주도 설계(DDD)는 반복적(Iterative) 과정이라는 점을 기억해야 합니다.
- 처음부터 지나치게 세분화된(Fine-grained) 마이크로서비스를 설계하지 않는 것이 중요합니다.
- 처음에는 보다 큰(Coarse-grained) 마이크로서비스를 설계하고,
- 필요에 따라 두 개의 작은 서비스로 분리하는 것이 더 쉽습니다.
- 반대로, 여러 개의 기존 마이크로서비스를 하나로 통합하는 것은 더 어려울 수 있습니다.
Example: Defining microservices for the Drone Delivery application
이전에 개발팀은 네 개의 애그리게이트(Aggregates) — Delivery, Package, Drone, Account 와
두 개의 도메인 서비스(Domain Services) — Scheduler, Supervisor 를 식별했습니다.
📌 마이크로서비스 후보 선정
✅ 명확한 마이크로서비스 후보:
- Delivery (배송)
- Package (패키지)
→ 이 두 개는 배송(Shipping) 경계 컨텍스트 내에서 독립적으로 동작할 수 있으므로,
→ 각각의 마이크로서비스로 분리하는 것이 합리적입니다.
✅ 도메인 서비스를 마이크로서비스로 구현:
- Scheduler (스케줄러)
- Supervisor (감독자)
→ 이 두 서비스는 다른 마이크로서비스들의 작업을 조정(Coordinate) 하므로
→ 독립적인 마이크로서비스로 구현하는 것이 적절합니다.
📌 "Drone" 및 "Account"의 처리 방식
Drone (드론)과 Account (계정)은 다른 경계 컨텍스트(Bounded Contexts)에 속합니다.
🔹 선택지 1:
- Scheduler가 직접 "Drone" 및 "Account" 경계 컨텍스트를 호출
- 즉, Scheduler 서비스에서 다른 컨텍스트의 API를 직접 호출하는 방식
🔹 선택지 2:
- Shipping 컨텍스트 내에 "Drone" 및 "Account" 마이크로서비스를 생성
- 이 서비스들은 API 또는 데이터 스키마를 "Shipping" 컨텍스트에 맞게 변환하는 역할 을 수행
🚀 실제 구현에서는 "Drone" 및 "Account" 마이크로서비스를 목(Mock) 서비스로 구현 하였습니다.
🚀 그러나, 다음과 같은 요소들을 고려해야 합니다.
✅ "Drone" 및 "Account" 마이크로서비스 설계 시 고려할 요소
1️⃣ 네트워크 오버헤드(Network Overhead)
- 다른 경계 컨텍스트의 서비스를 직접 호출할 경우 네트워크 지연이 증가할 가능성 이 있음
2️⃣ 데이터 스키마(Data Schema) 적합성 - 다른 경계 컨텍스트의 데이터 스키마가 "Shipping" 컨텍스트에 적합한가?
- 아니면 Shipping 컨텍스트에 맞게 변환하는 서비스가 필요할까?
3️⃣ 레거시 시스템(Legacy System)과의 연계 - 만약 "Drone" 또는 "Account" 컨텍스트가 레거시 시스템이라면,
- 반부패 계층(Anti-Corruption Layer, ACL) 을 생성하여 데이터 변환 및 API 통합을 수행하는 것이 필요할 수도 있음.
4️⃣ 팀 구조(Team Structure) - "Drone" 또는 "Account" 컨텍스트를 담당하는 팀과 원활하게 협력할 수 있는가?
- 만약 팀 간 소통이 어렵다면, 중재 역할을 하는 마이크로서비스를 추가로 생성하여 팀 간의 부담을 줄일 수 있음.
📌 비기능적 요구사항(Non-Functional Requirements) 고려
✅ "Ingestion" 마이크로서비스 추가
- 애플리케이션의 처리량(Throughput) 요구사항 을 고려하여,
- 클라이언트 요청을 수집(Ingest)하는 "Ingestion" 마이크로서비스를 별도로 생성
- 이 서비스는 로드 밸런싱(Load Leveling) 을 수행하며,
- 들어오는 요청을 버퍼(Buffer)에 저장한 후, Scheduler가 해당 요청을 읽어 처리하는 방식
✅ "Delivery History" 마이크로서비스 추가
- 지금까지 정의한 마이크로서비스들은 실시간(Real-Time)으로 패키지를 예약 및 배송하는 프로세스를 다루는 것 이었습니다.
- 그러나 과거 배송 이력을 장기적으로 저장(Long-Term Storage)하여 데이터 분석이 가능해야 함
- "Delivery" 서비스가 이를 처리할 수도 있었지만,
- 실시간 데이터 처리와 장기 데이터 저장의 요구사항이 다르므로 별도의 서비스로 분리
- 따라서, "Delivery History" 마이크로서비스를 추가로 생성
- "DeliveryTracking" 이벤트를 수신하여 데이터를 장기 저장소에 기록하는 역할 수행
다음 다이어그램은 이 관점의 디자인을 보여줍니다.
출처 : https://learn.microsoft.com/en-us/azure/architecture/microservices/model/microservice-boundaries
'Spring Microservice' 카테고리의 다른 글
CI/CD for microservices architectures (0) | 2025.02.26 |
---|---|
Microservices assessment and readiness (0) | 2025.02.26 |
Using tactical DDD to design microservices (0) | 2025.02.26 |
Using domain analysis to model microservices (0) | 2025.02.26 |
Microservices architecture design (0) | 2025.02.26 |