Event Storming
What are Domain Events?#
도메인 이벤트는 시스템에 어떤 요청이 들어왔을 때 시스템 내 서로 다른 서브도메인들에게 시스템의 상태가 변화했음을 알리기 위해 사용된다. 모든 요청은 하나의 작업으로 끝나지 않는 경우가 있다. 예를 들어 "유저는 상품을 구입한다" 라는 유스케이스가 있을때 시스템은 다음과 같은 일을 해야 할 수도 있다:
- 카트를 업데이트한다.
- 유저의 지갑에서 구매한 상품만큼의 금액을 인출한다.
- 배송 요청을 생성한다.
- 주문상세정보를 출력한다.
하나의 유스케이스에 대응하는 서비스에서 위의 네가지 작업을 모두 처리해서 주면 되지 않겠나 싶겠지만, 이는 잠재적으로 기술 부채를 키울 수 있다. 왜? 너무 많은 하위 도메인에 의존하여 타 모듈의 작은 수정에도 영향받을 수 있다. 테스팅을 위한 모킹 작업이 귀찮아진다. 트랜잭션 경계를 잘못 설정할 확률이 높아져 DB 병목현상이 발생할 가능성이 높아진다. 즉각적인 일관성이 필요없는 Eventual Consistency를 설계할 수 없어진다.
따라서 도메인 이벤트를 통하여 애그리게이트 간에 결합도 (coupling)를 낮추어 특정 이벤트가 발생하면 서로 다른 도메인 로직을 수행하도록 구성할 수 있다. 그러면 유스케이스를 구현하는 쪽에선 "상품 구매 요청이 접수됐다" 이벤트를 발행하고 카트, 지갑, 배송, 주문 각각의 하위도메인에서 해당 이벤트에 대한 핸들러를 각각 구현하여 낮은 결합도, 높은 응집력을 달성할 수 있게된다.
What is Event Storming?#
이벤트 스토밍은 알베르토 브랜돌리니에 의하여 제안된 회의방법론이다. 도메인 모델을 발견하고 소프트웨어 경계를 설계하는데 강력한 도구가 되어준다. 또한 비즈니스에 참여하는 가능한 모든 인원이 참여할 수 있어 동일한 멘탈 모델을 공유하는데 도움이 된다.
이벤트 스토밍의 핵심은 역시 이벤트이다. 추적할 가치가 있는 모든 이벤트를 브레인스토밍하여 각각의 포스트잇에 적어 붙여넣는다. 이벤트는 어떤 일이 이미 발생했음을 뜻하는 과거동사로 작성한다. 이벤트가 시간순에 따라 연속적으로 발생하는 경우, 왼쪽에서 오른쪽으로 정렬한다.
이벤트는 저절로 발행되지 않는다. 이벤트가 발생하는 원인인 커맨드를 식별한다. 각 커맨드는 액터 혹은 정책에 의해 트리거 될 수 있으며, 현재동사로 작성한다.
때때로 커맨드를 트리거하기 위해 읽기 모델이 필요할 수도 있는데, 최대한 간결하게 커맨드 혹은 액터 왼쪽에 붙여넣는 것을 원칙으로 한다.
액터는 시스템과 상호작용하는 모든 주체를 의미하며, 인간, 외부 시스템, API 등이 될 수 있다. 해당 커맨드를 실행하는 주체를 식별하여 커맨드 왼쪽에 붙여넣자.
정책은 이벤트와 커맨드를 연결하는 다리 역할을 한다. 핵심 비즈니스 규칙과 조건, 결정을 작성하는 곳이다.
Why Event Storming?#
도메인 전문가가 생각하는 시스템과 개발자가 생각하는 시스템 간에 간극을 메우고 도메인 공백을 찾아 구체화 할 수 있으며, 시각적인 결과물이 나오기 때문에 기억하기도 편하다. 비개발자들또한 참여할 수 있을 정도로 단순한 규칙 (화이트보드와 보드마카, 포스트잇만 있으면 됨.)이지만 개발자들에겐 바운디드 컨텍스트와 애그리게이트를 설계하는 중요한 지표가 될 수 있다.
Example of Event Storming#
Events#
시스템 내에서 이미 발생한 중요한 변화를 나타낸다. 도메인에서 가치 있는 비즈니스 이벤트를 표현한다. 예를 들어:
- 후원이 등록됨
- 주문이 완료됨
- 상품이 배송됨
- 이메일 인증이 완료됨
Commands#
- 후원 요청 제출
- 주문 생성
- 배송 요청
- 이메일 인증 요청
Actors#
- 사용자 → 후원 요청을 제출함.
- 관리자 → 특정 요청을 승인함
- 결제 시스템 → 결제 완료 후 주문을 확정함.
Read Models#
읽기 모델은 커맨드 실행을 위한 데이터 조회 모델이다. 복잡한 연산 없이 필요한 정보를 빠르게 조회하기 위해 읽기 전용 DB 레플리카를 구성할 수도 있다.
- 사용자 잔액 조회
- 상품 재고 확인
- 배송 상태 조회
Policies#
- "500만원이 초과하는 후원은 관리자의 승인을 받아야 한다": "후원이 등록됨" 이벤트 뒤와 "관리자 승인 요청" 커맨드 앞에 이 정책이 놓일 것이다.
- "재고가 0이면 주문을 생성할 수 없다": "주문 요청" 커맨드 실행 전, "재고 확인" 읽기 모델을 사용하여 조건 확인할 수 있다.
Bottlenecks & Problems#
이벤트 스토밍을 통해 발견할 수 있는 잠재적인 병목 현상과 문제점을 정리한다.
- "관리자 승인이 지연되면 후원 프로세스가 오래 걸릴 수 있다."
- "결제 시스템 장애가 발생하면 주문 처리가 중단될 수 있다."
- "재고 관리 정책이 명확하지 않으면 과잉 판매가 발생할 수도 있다."