본문 바로가기
IT 초보코딩의 세계/취미 코딩

[Micro Service] Micro Service 설계(이벤트 스토밍 워크숍 진행, 엑터 도출, 애그리거트 정의, 바운디드 컨텍스트, 컨텍스트 매핑) 2장

by 조이럭키7 2023. 5. 2.
반응형

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

이벤트 스토밍 워크숍 진행

     ● 워크숍 진행

        ⊙ 액터 도출

            → 커맨드까지 찾고 나면 커맨드를 실행하는 액터(Actor) 도출하는데 액터는 사용자 또는 조직, 역할자를 의미

            → 액터는 추상적으로 식별하지 않고 비즈니스를 수행하는 구체적인 역할을 고려해서 도출

            → 단순히 모든 업무에서 보편적으로 사용되는 회원이나 관리자로 정의하지 않고 특정 비즈니스를 실제로 수행하는 판매자, 구매자, 상품 관리자, 배송 관리자, 시스템 관리자와 같이 명확한 역할자를 도출하려고 노력해야 함

            → 액터를 도출하면서 이전에 식별하지 못했던 커맨드와 도메인 이벤트가 추가로 도출될 수 있는데 이 경우에도 추가로 식별되는 사항들을 모델링 공간에 붙이면 됨

            → 액터는 노란색의 작은 포스트잇을 사용해 커맨드의 왼쪽 아래에 붙여서 이 액터가 커맨드를 조작한다는 것을 명시적으로 표현

            → 액터가 각 업무와 밀접한 [판매자], [구매자], [주문자] 등으로 구체화 됨

            → 엑터를 도출하면서 문장을 만들어 식별한 커맨드와 이벤트를 검토

                  ∴ 판매자가 상품을 등록하면 [상품등록됨]이라는 이벤트가 발생함으로써 시스템이 동작

                  ∴ 구매자가 상품 주문을 취소하면 [상품주문취소됨] 이벤트가 발생하고 이어서 주문 취소된 상품의 재고를 변경하는 [재고변경됨] 이벤트가 발생함으로써 시스템이 동작

            → 문장이 자연스럽지 않다면 자연스럽게 커맨드와 도메인 이벤트를 변경하거나 새로 도출

            → 도메인 이벤트, 외부 시스템. 커맨드, 액터를 찾아봄으로써 전체 시스템의 큰 그림을 조망할 수 있으며 액터를 식별함으로써 주요 사용자나 역할자의 주요 프로세스도 그려볼 수 있음

            → 프로세스 중간중간 붙어있는 핫스폿을 표시한 포스트잇을 통해 프로세스 구현을 위해 어떤 이슈나 문제, 해결할 사항들이 있다는 것도 알 수 있게 됨

            → 지금까지 비즈니스 관점에서 워크숍을 진행했다면 이후부터는 설계 수준으로 진행

 

        ⊙ 애그리거트 정의

            → 애그리거트는 커맨드와 도메인 이벤트가 영향을 주는 데이터 요소로 도메인의 실체 개념을 표현하는 객체인 엔티티

            → 애그리거트는 노란색 포스트잇에 애그리거트명을 작성해서 커맨드와 도메인 이벤트 사이의 상단에 겹쳐서 붙임

            → 액터와 마찬가지로 애그리거트도 구체적인 표현으로 도출하는 것이 좋은데 그 이유는 애그리거트를 구체적으로 식별할수록 컨텍스트의 경계를 식별하는 데 유용하기 때문

            → [회원], [결제], [상품], [배송] 등의 애그리거트를 정의

 

        ⊙ 바운디드 컨텍스트

            → 애그리거트를 보면 일부 애그리거트는 이름이 같거나 유사한 것을 알 수 있는데  이처럼 이름이 같거나 유사한 애그리거트를 완전히 다른 애그리거트와 구분해서 경계를 그리고 그동안 도출했던 도메인 이벤트, 커맨드, 액터. 애그리거트를 모두 고려해서 경계를 식별

            → 경계는 마커펜이나 얇은 라인 테이프로 표시할 수 있지만 이 경계는 애그리거트를 그룹화하는 크기 수준에 따라 바뀔 수 있으므로 마커펜보다는 언제든지 수정 가능한 라인 테이프로 표시하 는 것이 좋음

            → 이 경계를 바운디드 컨텍스트라고 하는데 바운디드 컨텍스트에는 이름을 부여

            → 컨텍스트의 이름은 바운디드 컨텍스트 내의 애그리거트 이름으로 정의

            → 컨텍스트 내에 여러 개 의 애그리거트 이름이 있는 경우 전체를 아우를 수 있는 대표 이름을 정함

            → 애그리거트가 식별된 결과를 보면 동일한 이름의 애그리거트가 서로 다른 공간에 떨어져 있는 것을 발견할 수도 있는데 이 경우 해당 애그리거트가 많이 식별된 위치로 떨어져 있던 모든 관련 포스트잇(애그리거트 및 도메인 이벤트, 커맨드, 액터)을 옮길 수도 있는데 이것은 기능을 제공할 책임들을 응집성 있도록 동일한 애그리거트 중심으로 모듈화해야 한다는 것을 의미

            → 구체적으로 애그리거트를 식별했다면 애그리거트가 달라지는 지점에서 어떻게 경계를 나눠야 할지 고민될 것

            → [상품], [카테고리]가 도출된 경우 [상품], [카테고리] 사이에 경계를 둘 수도 있지만 상품과 카테고리를 묶어 [상품]이라는 바운디드 컨텍스트로 정의할 수 도 있음

            → 다른 케이스로 [구매] 컨텍스트에 [주문], [결제]. [주문아이템]애그리거트로 식별됐지만 주문할 아이템을 검색한 후 주문에서 결제까지 하나의 흐름으로 이어지기 때문에 각각을 분리하지 않고 [구매] 컨텍스트로 묶어서 정의할 수 도 있음

 

        ⊙ 정책을 도출하면서 연관관계 생각하기

            → 현재까지 파악된 관계만으로도 외부 시스템과 각 바운디드 컨텍스트 간의 관계를 그릴 수 있음

            → 정책은 라일락색 포스트잇을 사용하는데 정책은 이벤트 뒤에 따라오는 반 응적인 비즈니스 로직으로 어딘가에 존재하는 커맨드를 동작하게 함

            → 정책은 다음과 같이 정의

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

            → 정책은 도메인 이벤트와 커맨드 사이에 존재

            → 이러한 정책이 호출하는 커맨드는 같은 바운디드 컨텍스트 내에 존재할 수도 있고 다른 바운디드 컨텍스트에 존재할 수도 있기 때문에 정책을 도출함으로써 다른 바운디드 컨텍스트와의 관계를 식별할 수 있음

            → 구매가 완료된 경우나 구매가 취소되는 경우 상품의 재고 수량이 변경돼야 한다는 정책을 도출했는데 이는 구매 바운디드 컨텍스트에서 [구입완료됨], [결제취소됨] 이벤트 이후 [재고변경] 이라는 정책으로 말미암아 [상품재고수정됨] 이벤트 발생을 위해 상품 바운디드 컨텍스트의 [상품재고수정] 커맨드가 호출됨

            → 구매 컨텍스트에서 구매가 완료되면 [배송요청됨]이라는 이벤트가 발생하고 이 이벤트와 연관된 [배송생성]이라는 정책으로 배송 컨텍스트의 [배송접수]라는 커맨드를 트리거한다는 사실을 알 수 있는데 파란색 라인 테이프를 통해 흐름의 방향을 화살표로 표현

   

    ⊙ 컨텍스트 매핑

            → 앞의 과정까지 진행하면 대략의 바운디드 컨텍스트가 식별되고 각 바운디드 컨텍스트 간의 관계가 파악됨

            → 다음으로 이러한 관계를 별도의 컨텍스트 맵으로 표현해 보면 컨텍스트 관계를 작성할 때는 호출 관계의 방향을 고려해야 하고 호출할 때 호출 방식, 동기 방식의 호출이 필요한지, 비동기 방식의 호출이 필요한지 판단해서 작성해야 함

            → 호출 방식은 데이터의 일관성 측면과 컨텍스트의 가용성 측면을 고려해서 선택

            → 컨텍스트 간에 항상 일관된 데이터가 필요한 관계는 동기 호출로 표현하고 결과적 일관성으로 충분히 처리 가능한 관계는 비동기 방식의 호출로 표현

            → 일반적으로 동기 방식은 실시간 동시 처리를 위해 호출하고 응답을 대기하는 방식으로 두 컨텍스트 간의 의존도가 높아지는 반면 비동기 방식은 컨텍스트 내에서 처리한 후 이벤트를 발행해 연관된 다른 컨텍스트가 이벤트를 받아 처리할 수 있게 하는 방식으로 두 컨텍스트 간의 의존성을 낮출 수 있기 때문에 반드시 실시간 정합성이 필요한 경우가 아니라면 비동기 방식의 연계를 고려하는 것이 좋음

            → 비동기 방식의 연계로 두 컨텍스트 사이의 결합도를 낮춘다면 각 컨텍스트들의 독립성과 탄력성이 강화될 수 있음

            → 컨텍스트 맵은 이벤트 스토밍 워크숍에서 식별한 바운디드 컨텍스트명을 스티커에 적어 별도 공간에 붙이고 관계를 표현하면 됨

            → 동기 호출은 실선으로 비동기 호출은 점선으로 표현

            → 수정하기 편한 색깔이 다른 끈 테이프를 사용할 수도 있는데 클라이언트에서는 각 컨텍스트에 접근해서 데이터를 직접 관리할 수 있으므로 동기 방식으로 정의했고, 각 컨텍스트와 연관관계에 있는 외부 시스템도 모두 동기 방식으로 정의

            → 먼저 고객이 상품을 주문할 때 상품 구매를 위해 클라이언트를 통해 구매 컨텍스트에 동기 방식으로 접근하면 구매 컨텍스트는 구매하려는 상품(주문 아이템)의 현재 가격을 가져오기 위해 상품 컨텍스트에 동기 방식으로 연동하고 회원 컨텍스트에도 현재의 결제 정보와 배송지 정보를 가져오기 위해 동기 방식으로 연동하지만 구매 컨텍스트와 배송 컨텍스트는 연관관계가 비동기로 정의됐는데 이러한 경우 배송 컨텍스트에 장애가 발생한 경우에도 주문을 계속 처리할 수 있는 고가용성을 보장

            → 최근에는 비동기 연계를 위한 메시지 브로커의 성능과 안정성이 높아져서 동기 방식의 연동은 필요한 경우에만 사용하고 많은 부분에 비동기 연동을 통해 데이터 정합성을 맞추는 경우가 많아져서 비동기 연동 방식은 동기 방식에 비해 마이크로서비스가 독립성을 갖게 하고 높은 가용성을 보장받을 수 있게 함

            → 도출된 바운디드 컨텍스트는 마이크로서비스 후보가 되는데 최종적으로 마이크로서비스로 정의하려면 추가로 다음과 같은 질문을 고려해서 판단

                  ∴ (비즈니스 측면) 비즈니스 프로세스를 수행하기 위한 하나의 맥락의 단위로 구분될 수 있는가?

                  ∴ (데이터 관점) 마이크로서비스별로 분리된 데이터를 정의할 수 있는가?

                  ∴ (운영 조직 측면) 하나의 팀이 독립적으로 운영 가능한 단위인가?

                  ∴ (배포 측면) 독립적으로 배포 가능한 단위인가?

                  ∴ (변경 영향도) 변경 시 영향을 받는 마이크로서비스가 존재하는가?

                  ∴ (클라우드/MSA 도입 목적 측면) 도입을 통한 기대효과를 충분히 활용할 수 있는가?

            → 이를 모두 만족한다면 바운디드 컨텍스트를 최종 마이크로서비스로 식별하고 만족하지 못한다면 각 질문의 결과에 따라 바운디드 컨텍스트를 분리하거나 통합해서 마이크로서비스로 식별

            → 이벤트 스토밍 결과를 프로젝트가 진행되는 공간에 그대로 붙여 놓아서 계속 보완하고 리뷰될 수 있게 하는 것이 가장 좋고 최종적인 문서나 협업 시스템에 기록해 팀원들이 항상 참고하게 할 수도 있음

            → 실제 프로젝트에서는 개발팀 사무실의 벽면 가득 이벤트 스토밍 워크숍 결과를 붙여 놓고 계속해서 이슈에 대해 고민하고 새로운 기능을 구체화하면서 프로젝트를 진행하는 것이 좋음

 

        ⊙ 마이크로서비스 상세 설계를 위한 입력물

            → 이벤트 스토밍 결과는 서비스 상세 설계를 위한 출발점이 됨

            → 마이크로서비스 별로 커맨드, 도메인 이벤트. 애그리거트, 서비스 연계 및 정책, 핫스팟, API, 도메인 이벤트, 데이터, 리스크 등으로 정리할 수 있음

            → 이 자료는 마이크로서비스의 프런트엔드 모델링과 백엔드 모델링에 활용

반응형

댓글