영상요약및 번역본
🎭 배우들이 DDD 세계를 지배할 수 있습니다
Hannes Lowette – NDC Porto 2022 발표 요약
1. 발표 개요 및 문제 정의
발표자는 벨기에 출신의 Hannes로, DDD(Domain-Driven Design)와 CQRS(Command Query Responsibility Segregation) 기반 시스템을 Akka.NET으로 구현하는 방법을 소개함.
BeerSender.NET이라는 맥주 배송 및 추적 시스템을 예시로 사용함.
벨기에의 다양한 맥주를 친구들에게 보내려다, 국제 배송 및 통관 문제로 여러 번 반송, 추가 비용, 복잡한 추적 과정을 겪음.
이 경험을 바탕으로 "맥주 추적 시스템"의 필요성을 느끼고, 이를 .NET 프레임워크로 개발하기로 함.
2. DDD와 CQRS, Event Sourcing 개념 정리
DDD
비즈니스와 개발팀이 **동일한 언어(유비쿼터스 언어)**를 사용하여 소프트웨어를 설계함.
시스템 내에서 의미가 달라지는 **경계(바운디드 컨텍스트)**를 구분하여, 각 컨텍스트마다 명확한 책임과 언어를 정의함.
**Aggregate(집합체)**는 비즈니스 로직의 단위이자 이벤트가 발생하는 중심.
CQRS
**명령(Command)**과 **조회(Query)**를 분리하여 각각 독립적으로 확장 및 최적화할 수 있게 함.
명령은 시스템의 상태를 변경하고, 조회는 상태를 읽기만 함.
이벤트는 명령 실행 후 발생하며, 읽기 저장소를 최신 상태로 유지하는 데 사용됨.
Event Sourcing
상태 변화의 모든 이벤트를 저장하고, 이를 재생하여 현재 상태를 복원함.
예: 쇼핑카트에서 상품을 추가/삭제한 모든 과정을 이벤트로 저장하여, 추천 엔진 등에서 활용 가능함.
3. Akka.NET과 Actor 모델의 특징
Akka.NET은 Scala 기반 Akka의 .NET 포트로, 메시지 기반의 Actor 모델을 구현함.
소프트웨어를 현실 세계처럼 객체(Actor) 간 메시지 교환으로 모델링함.
특징:
비동기 메시지 기반
멀티코어 및 클러스터 활용 가능
높은 확장성과 복원력
Actor는 자신의 상태와 행동을 가지며, 오직 메시지로만 상호작용함.
메시지는 순차적으로 처리되어, 동시성 문제를 피할 수 있음.
4. Actor 시스템 구조 및 메시지 처리
Actor는 특정 클래스를 상속받아 구현함.
메시지는 POCO(Plain Old CLR Object)로 자유롭게 정의 가능.
메시지를 처리하면서 메시지 객체를 변경해서는 안 됨.
클러스터 환경에서는 메시지가 직렬화/역직렬화됨.
성능: 단일 서버에서 초당 수백만~수천만 메시지 처리 가능.
Actor System은 Actor 생성/관리/메시지 분배/이벤트 버스 관리 등을 담당함.
Actor는 트리 구조로 구성되며, 부모-자식 관계가 중요함.
5. Actor의 감독 전략 (Supervision)
ReceiveActor: 타입별 메시지 핸들러 등록 가능
자식 Actor는 context.actorOf로 생성하며, 이름은 고유해야 함.
감독 전략:
부모 Actor는 자식 Actor의 예외 상황을 처리함
Resume(계속), Stop(중지), Restart(재시작), Escalate(상위로 전달)
예: 자식 Actor 중 하나라도 실패하면 전체 작업을 중단하는 전략 등 적용 가능.
Erlang 사례: 2백만 라인의 텔레콤 시스템에서 연간 31ms 다운타임 기록
6. Akka Persistence와 Event Sourcing
Akka Persistence는 Actor의 상태를 이벤트 소싱 방식으로 영속화할 수 있는 라이브러리.
Actor 재생성 시, 스냅샷과 이벤트를 순서대로 재생하여 상태 복원.
모든 Actor에 적용하면 성능 저하 우려 → 필요한 경우에만 사용 권장
상태는 별도의 State 객체로 관리
메시지 처리 방식:
Command: 명령 처리 시 persist 호출
Recover: 복구 시 apply만 수행
스냅샷 저장은 비동기로 처리되며, SnapshotOffer 메시지로 상태 객체 복원 가능
7. Akka.NET과 DDD의 궁합
DDD의 현실 세계 모델링과 Actor의 메시지 기반 모델이 자연스럽게 어울림
Akka.NET은 메시지 기반 처리, 이벤트 소싱, 이벤트 버스 등 CQRS 시스템 구축에 적합
클러스터링을 통해 선형 확장 가능
8. Aggregate 구현 및 테스트 전략
Aggregate는 외부 의존성 없이 구현, 저장소 정보도 모름
명령을 전달하면 이벤트 목록을 반환함 (상태를 직접 변경하지 않음)
apply를 통해 상태를 변경
테스트:
Given (이전 이벤트)
When (명령)
Then (예상 이벤트)
C#의 record 타입을 활용한 깊은 비교 및 가독성 확보
제품 담당자도 이해할 수 있는 테스트 시나리오 작성
9. CQRS 아키텍처 내 Aggregate Actor
Aggregate를 Actor로 감싸서 명령을 처리하고 이벤트를 저장/적용함
Persistence ID는 Aggregate 타입 + ID 조합으로 생성
이벤트 발생 시 내부 이벤트 스트림에도 publish하여 읽기 모델에 반영
Actor 계층:
Aggregate Manager → Aggregate Actor 생성 및 참조 관리
Command Router → 명령을 Aggregate Manager로 전달
Projector → 이벤트를 읽기 저장소(DB 등)에 반영
확장 전략:
라우팅: 라운드로빈, 최소 인박스, Consistent Hashing
클러스터 환경에서는 샤딩(Sharding) 사용 가능
10. 실전 운영 팁
UI와 이벤트 스트림을 연동 → 실시간 UI 구현 가능
HOCON 설정 → 설정 정보를 외부 파일로 관리
클러스터링 학습 필요
로깅 시스템과 연동 가능
모니터링:
Petabridge Phobos (유료)
OpenTelemetry 연동
11. 학습 자료 및 결론
Petabridge 부트캠프 (무료)
Petabridge 블로그 (심층 설명)
유료 강의 (원격, 클러스터링, 디자인 패턴 등)
🔑 결론
DDD와 Actor 모델은 매우 잘 어울린다.
비즈니스와 개발 모두가 이해 가능한 표현력 높은 시스템을 만들 수 있다.
링크 : https://lilys.ai/digest/4965701/4291743?s=1¬eVersionId=569965