4 분 소요


책커버

5.4 이벤트 스토밍을 통한 마이크로서비스 도출


이벤트 스토밍이란 DDD 설계를 가속화할 수 있도록 이벤트 중심으로 이해관계자들이 모여 브레인 스토밍을 하는 워크숍을 말합니다.

5.4.1 이벤트 스토밍 워크숍 준비

  • 워크숍 준비
    워크숍을 위해서는 다음과 같은 사항이 필요합니다.
    1. 공간: 깨끗한 벽
    2. 참가자: 모든 이해관계자
    3. 준비물: 흰색 전지, 다양한 색의 포스트잇, 다양한 색의 라인 테이프
    4. 열린 분위기: 다양한 이해관계자들이 부담 없이 의견을 낼 수 있게 분위기를 조성하는 퍼실리테이터

  • 스티커 유형별 의미

msa5_2_1 msa5_2_2

5.4.2 이벤트 스토밍 워크숍 진행

위와 같이 워크숍 준비가 마무리 되면 워크숍을 진행합니다.

워크숍은 다음과 같은 순서로 진행됩니다.

1. 도메인 이벤트 찾기


도메인 이벤트는 비지니스의 어떤 상태를 생성, 변경, 삭제하는 요소입니다.

비지니스 흐름에서 발생한 이벤트에 초점을 맞춰 도메인 이벤트를 찾아 벽에 붙입니다.

이벤트는 오른쪽으로 갈 수록 나중에 진행되는 것이며, 이벤트가 연쇄적으로 발생하는 경우는 바로 옆, 조건에 따라 대체적으로 발생하는 경우는 평행하게 붙입니다.

2. 외부 시스템 도출


이벤트가 동작하면서 레거시 시스템이나 외부 시스템과의 연계가 필요하다면 이를 별도의 스티커로 붙이고 이벤트와 화살표로 관계를 표시합니다.

3. 커맨드 도출


이벤트를 동작하게 하는 커맨드를(Command)를 찾습니다.

커멘드를 작성할 때 주의할 점은 이벤트를 동사형으로 작성해야 합니다. 또한 하나의 커맨드는 여러 이벤트를 동시, 혹은 연속적으로 동작 시킬 수 있스므로 이를 염두하여 작성합니다.

4. 핫스폿 도출


워크숍 진행 중 의문이 들거나 워크숍 시간 내에 해결 할 수 없는 것들은 따로 정리해 두는 것이 좋습니다. 이를 핫스폿이라 합니다.

5. 액터 도출


커맨드를 실행하는 주체를 액터라고 합니다. 액터는 사용자가 될 수도 있고, 조직이나 담당자가 될 수도 있습니다.

액터를 도출할 때에는 특정 비지니스를 수행하는 명확한 역활자를 도출하려고 노력해야 합니다.

이렇게 액터를 도출해 내면 지금까지 식별한 커맨드와 이벤트를 바탕으로 문장화 해봅니다.

만약 문장이 자연스럽지 않다면, 지금까지 작성한 카드들을 변경하거나 새로 도출하며 문장이 자연스럽도록 반복합니다.

6. 애그리거트 정의


애그리거트란 도메인의 실체 개념을 표현하는 객체입니다. 자세한 것은 DDD 철저입문 12장(링크)에서 확인하시면 됩니다.

애그리거트는 구체적인 표현으로 도출하는 것이 좋습니다. 그 이유는 애그리거트를 구체적으로 식별할수록 컨텍스트의 경계를 구분하는데 유용하기 때문입니다.

7. 바운디드 컨텍스트 그리기


이름이 같거나 유사한 애그리거트를 완전히 다른 애그리거트와 구분하여 경계를 그립니다.

이렇게 식별된 경계를 바운디드 컨텍스트라고 합니다. 각 바운디드 컨텍스트의 이름은 내부의 애그리거트 이름으로 정의합니다. 만약 여러 개의 애그리거트를 포함하고 있는 경우에는 전체를 아우를 수 있는 이름으로 정의합니다.

8. 정책 도출하기


다음으로 정책을 도출합니다. 정책은 이벤트 뒤에 따라오는 반응적인 비지니스 로직을 뜻합니다.

정책은 다음과 같이 정의합니다

[도메인 이벤트]할 때는 항상 [커맨드]한다.

따라서 정책은 도메인 이벤트와 커맨드 사이에 존재합니다.

주의할 점은, 이러한 정책이 호출하는 커맨드는 같은 바운디드 컨텍스트 안에 있을 수 있지만 다른 컨텍스트 안에 존재할 수도 있습니다.

msa5_2_3

예를 들어, 위 그림 5.32에서 구매 컨텍스트의 [재고변경]이라는 정책은 상품 컨텍스트의 [상품재고수정]이라는 커맨드를 호출합니다.

9. 컨텍스트 매핑


여기까지 진행하면 바운디드 컨텍스트가 식별되고 각 바운디드 컨택스트 간의 관계가 파악이 됩니다.

이렇게 파악된 관계를 별도의 맵으로 표현하는 것이 컨텍스트 매핑이라 합니다.

컨텍스트 매핑을 할 때 주의할 점은 각 호출 방식이 동기 방식으로 할 것인지, 비동기 방식으로 할 것인지 고려하며 작성해야 합니다.

일반적으로 컨텍스트 간에 일관된 데이터가 필요한 관계는 동기 방식을, 결과적 일관성으로 해도 무관한 경우에는 비동기 방식으로 호출합니다.

동기 방식은 두 컨텍스트간의 의존도 상승, 비동기 방식은 의존성 하락

하지만 최근에는 비동기 연계를 위한 메시지 브로커의 성능과 안정성이 높아져 동기 방식은 꼭 필요한 경우에만 사용하고 많은 부분을 비동기 방식으로 처리합니다.


이렇게 도출된 바운디드 컨텍스트가 마이크로서비스의 후보가 됩니다.

마지막으로 다음 6가지 측면을 고려한 뒤 최종 마이크로 서비스로 식별합니다.

  • (비지니스 측면) 비지니스 프로세스를 위한 하나의 맥락 단위로 구분 가능한가?
  • (데이터) 분리된 데이터를 정의할 수 있는가?
  • (운영 조직) 팀이 독립적으로 운영 가능한 단위인가?
  • (배포) 독립적으로 배포 가능한 단위인가?
  • (변경 영향) 변경 시 영향을 받는 타 서비스가 존재하는가?
  • (클라우드) 토입을 통한 기대효과를 충분히 활용 가능한가?

5.5 마이크로서비스 상세설계


5.5.2 백엔드 모델링


헥사고날 아키텍처를 정용해 외부 영역과 내부 영역으로 구분하여 구축합니다.

예를 들어, 이벤트 스토밍의 커맨드는 인바운드 어댑터의 하나인 REST API가 되고, 애그리거트는 내부 영역인 도메인 모델이 됩니다.

이후 개략적인 모델링이 끝나면 좀더 구체적인 구현을 위해 프론트엔드와 연계되는 API 설계를 해야 합니다.

API 설계


바람직한 REST API 설계를 위해 레오나르도 리처드슨의 REST API 성숙도 모델 중 레벨 2를 지향하여 작성합니다.

API 설계 문서화


완료된 API 설계를 문서화 후 공유하여 보다 나은 협업 환경을 구축합니다.

5.6 도메인 모델링


도메인 모델링은 도메인 주도 마이크로서비스를 설계하는 데 중요한 부분입니다.

책에서 소개한 도메인 모델링은 두 가지 구조가 있습니다.

msa5_2_4 msa5_2_5

두 구조의 차이는 도메인 모델을 중심으로 두는지, 도메인 모델 없이 DTO를 중심에 두는지의 차이입니다.

트랜잭션 스크립트 구조의 단점은 시스템이 복잠해 질 수록 비대하지는 점이 있습니다.

그렇다고 단적으로 도메인 모델이 좋다고 말할수는 없습니다. 단순한 로직을 처리하는 MSA일 경우 트랜잭션 스크립트 구조로 만들어도 무방합니다.

이를 결정하는 것은 팀의 역량 수준을 고려하여 결정하는 것을 추천합니다.

5.6.1 DDD의 전술적 설계


기존 객체 모델링 방식은 자유도가 높아 여러 층의 복잡한 계층 구조를 만들게 될 가능성이 높습니다.

이를 방지하기 위해 객체들의 역활에 따른 유형을 정의하고 이에 따라 모델링 하는 것이 중요합니다.

엔티티


엔티티는 다른 엔티티와 구별할 수 있는 식별자를 가진 객체입니다.

자세한 것은 도메인 주도 설계 3을 참조하세요.

값 객체


값 객체는 각 속성이 개별적으로 변화하지 않는 객체입니다. 객체 내부의 속성들의 합에 의해 전체 개념이 부여됩니다.

또한 객체 내부의 속성이 수정되는 것이 아닌, 전체 객체가 한번에 생성되거나 삭제됩니다.

자세한 것은 도메인 주도 설계 2을 참조하세요.

표준 타입


대상의 타입을 나타내는 서술적 객체입니다. 값 객체의 속성을 구분하는 용도로 사용합니다. (일반적으로 ENUM 타입)

애그리거트


애그리거트는 위의 열거된 엔티티, 값 객체, 표준 타입의 묶음입니다.

각 속성들 간에는 비지니스 의존관계를 맺고 있습니다. 따라서 일반적으로 애그리거트는 트랜잭션의 기본 단위가 됩니다.

애그리거트 내에 있는 엔티티 중 가장 상위의 엔티티를 애그리거트 루트라고 합니다. 이 애그리거트 루트를 통해서만 내부의 엔티티나 값 객체를 변경할 수 있게 해야 합니다.

하나의 컨텍스트안에 여러 개의 애그리거트가 존재하여 다른 애그리거트를 참조해야 하는 경우에는 직접 참조하지 않고 애그리거트 루트의 식별자를 통해 참조해야 합니다.

애그리거트 간의 데이터 일관성이 필요한 경우에는 비동기 방식을 이용하여 결과적 일관성을 유지합니다.

도메인 서비스


도메인의 비지니스 로직 처리가 엔티티나 값 객체에 속하지 않을 때 단독 객체를 만들어 처리합니다. 이를 도메인 서비스라고 합니다.

도메인 서비스에서는 상태를 관리하지 않고 행위만 존재합니다. 따라서 특정 작업을 처리하고 상태를 본인이 가지고 있지 않고 엔티티나 값 객체에 전달합니다.

자세한 것은 도메인 주도 설계 4을 참조하세요.

도메인 이벤트


이전의 이벤트 스토밍에서 나왔던 그 도메인 이벤트가 구현된 객체입니다.

msa5_2_6

위의 예제에서 주문 엔티티와 주문아이템 엔티티가 생성되어 저장됨과 동시에 구매완료됨 이벤트가 발행되는 것을 확인 할 수 있습니다.

이 도메인 이벤트는 주문에 따른 주요 정보를 담고 있는 객체입니다. 따라서 이 객체는 주문 처리를 수행하는 트랜잭션과 묶어서 실행되야 합니다.

:bulb: 본 글은
도메인 주도 설계 시리즈로 작성 됩니다.
도메인 주도 설계로 시작하는 마이크로서비스 개발 5-1
도메인 주도 설계로 시작하는 마이크로서비스 개발 5-2

댓글남기기