마이크로서비스 모델링 ⑦ : BackEnd 설계 - 도메인모델링

Updated:

마이크로서비스 모델링 ⑦ : 도메인 모델링

도메인 모델링은 백엔드 모델링의 한 부분이지만 도메인 주도 마이크로서비스를 설계하는데 중요한 부분이므로 이번 포스트에서 상세히 설명하고자 한다.

마이크로서비스 내부 구조는 폴리그랏 하게 접근할 수 있다 . 폴리그랏하다는 의미는 어플리케이션을 구현하는 언어나 데이터를 저장하는 저장소를 서비스 마다 다양하게 가져갈 수 있다는 말 임과 동시에 내부 아키텍처 구조를 서비스 특성에 맞게 다양하게 가져 갈수 있다는 것도 의미한다.

따라서 서비스의 내부 영역의 구조를 도메인 모델 중심으로 가져갈 수도 있고 트랜젝션 스크립트 형태로 가져갈 수 도 있다. 아래 그림 1은 도메인 모델 중심의 구조이다. 도메인 모델을 중심으로 모델링을 수행해야 하며 서비스가 모든 로직을 처리하지 않고 비지니스로직이 도메인 모델로 위임되어 적절히 분산될 것이다. 그림 2는 도메인 모델이 없는 트랜잭션 스크립트의 구조이다. DTO는 데이터 홀더로써의 역할만 수행할 것이며 서비스가 많은 로직을 보유하게 됨으로써 시스템이 복잡해 질 수로 비대해 질 수 있다.

도메인 모델 형태의 헥사고널 구조 그림 1 도메인 모델 형태의 헥사고널 구조

트랜젝션 스크립트 형태의 헥사고널 구조
그림 2 트랜젝션 스크립트 형태의 헥사고널 구조

단순한 로직인 경우에 트랜젝션 스크립트 구조로 진행 되도 무방하다. 그렇지만 비지니스가 복잡해 질 수록 비지니스 개념들을 잘 구조화 할 수 있는 도메인 모델 구조가 효과적이다. 도메인 모델 구조는 복잡함을 다루어 쉽게 표현할 수 있는 구조를 제공해 준다.

이러한 내부 구조를 정의하기 위해서는 서비스가 제공할 기능이 어떠한 가도 고민해야 갰지만 팀의 역량 수준도 고려되어 한다. 백엔드 엔지니어들에게 객체지향 설계 및 문화가 준비되어 있는지 능숙하지 판단해야 한다.

내부 영역을 도메인 모델 구조로 정의하였을 경우에 필요한 모델링 방식이 도메인 모델링이다.

DDD전술적 설계(도메인 모델링 구성요소)

도메인 모델링은 객체모델링의 의미로 광범위하게 사용되고 있었으나 여기서는 DDD의 전술적 설계를 활용하여 객체모델링을 진행하는 방식으로 언급하겠다.

기존의 객체 모델링 방식은 자유도가 높아 문제영역을 파고들게 되면 될 수록 여러 층의 복잡한 계층 구조를 만들게 될 가능성이 높다. 그래서 이를 정리하기 위해 객체들의 역할에 따른 유형을 정의하고 이런 규칙에 따라 모델링하면 단순하고 이해하기 편해지는데, 이러한 설계 기법을 DDD의 전술적 설계에서 제공하고 있다. DDD의 전술적 설계에 다양한 구성요소가 있지만 도메인 모델링을 위한 객체 요소 중심으로 살펴보자.

엔터티

엔터티(Entity)는 다른 엔티티들과의 특성을 구별할 수 있는 식별자를 가진 객체이다. 식별자는 고유 하되 엔티티의 속성 및 상태는 계속 변할 수 있다. 도메인에서 개별성(Individuality)이 인지되는 개념을 엔티티로 식별하며 고유 식별자와 변화가능성(mutability)가 엔티티와 값 객체를 구분하는 차이이다. 아래 그림3 을 보면 장바구니는 장바구니 식별자에 의해 구분 가능하며 전체상품가격등이 개별적으로 수시로 변경될 수 있기 때문에 엔티티로 모델링하였다.

값 객체

값 객체(Value Object) 는 각 속성이 개별적으로 변화하지 않는 개념적 완전성 을 모델링한다. 따라서 값 객체는 속성과 속성의 합에 의해서 전체 개념이 부여되며 개별 속성이 별개로 수정되지 않고 전체 객체가 한번에 생성되거나 삭제되는 객체이다. 엔티티와 같이 식별자의 차이에 따라 구별되지 않고 속성과 속성으로 이루어진 값의 차이 비교에 의해 동일함이 결정된다. ‘도메인 주도 설계 핵심’의 저자 반버논은 값 객체의 특성을 다음과 같이 정의한다.

  • 도메인 내의 어떤 대상을 측정하고, 수량 화하고, 설명한다.
  • 관련 특징을 모은 필수 단위로 개념적 전체를 모델링한다.
  • 측정이나 설명이 변경될 땐 완벽히 대체 가능하다.
  • 다른 값과 등가성을 사용해 비교할 수 있다.
  • 값인 객체는 일단 생성되면 변경할 수 없다. 아래 그림을 보면 쇼핑 품목을 전체로 개념으로 파악하여 값 객체로 모델링하였다. 쇼핑 품목의 개별 속성은 변경되지 않고 추가,삭제만 가능하다.

표준 타입

표준 타입은 대상의 타입을 나타내는 서술적 객체이다. 엔터티나 값 객체의 속성을 구분해주는 용도로 사용한다. 만약 전화번호를 값 객체로 모델링 했다면 이 전화번호가 집 전화인지 핸드폰 전화 또는 회사전화번호인지 구분할 필요가 있다. 예전에는 보통 코드 값으로 모델링하였으나 이러한 방식은 매핑표가 필요하며 가독성이 떨어져 이해하기 어렵다. 컨텍스트에 맞는 이해 가능한 유비쿼터스 용어로 정의함이 바람직하다. 자바언어에서는 보통 자바의 열거 형으로 정의한다. 아래 그림을 보면 배송 유형이라는 열거 형으로 로켓배송과 판매자배송을 구분하여 표준타입으로 정의하고 있다.

도메인 모델 예시
그림3 도메인 모델 예시

어그리게잇

이렇게 엔터티와 값 객체로 모델링하게 되면 자연스럽게 객체간의 계층구조가 생성된다. 이때 최고 상위의 객체를 루트 엔터티라 하며 루트 엔터티를 중심으로 구분되는 군집이 생긴다. 이 때 루트 엔터티를 어그리게잇이라 표기하며 이렇게 군집으로 구분할 수 있는 단위를 어그리게잇이라 말한다.

이런 어그리게잇은 1~2개의 엔터티, 값 객체, 표준타입등으로 구성되는데 이들 간에서는 비지니스 의존관계를 가지고 있으며 비지니스 정합성을 맞출 필요가 있다. 따라서 이 어그리게잇 단위가 트랜잭션의 기본 단위가 된다.

보통 하나의 컨텍스트에 하나의 어그리게잇이 식별되나 하나의 컨텍스트 안에 여러 개의 어그리게잇이 존재할 수 있다. 이런 경우 다른 어그리게잇을 참조해야 할 경우가 있다면 직접 참조하지 않고 식별자를 통해 참조하게 한다. 직접 참조하게 되는 경우 어그리게잇 단위의 트랜잭션 처리도 힘들고 의존관계가 점점 복잡해 질 것이다.

또한 일반적으로 컨텍스트 경계를 마이크로서비스로 식별하게 되는데 어그리게잇 또한 별도의 마이크로서비스 후보가 될 수 있다. 그런데 같은 컨텍스트 내에 여러 개의 어그리게잇이 존재할 때 다른 어그리게잇의 클래스를 직접 참조하게 하면 별도로 마이크로서비스로 분리하기 힘들 것이다. 따라서 아래 그림과 같이 어그리게잇 간 참조는 루트엔티티의 식별자를 활용하여 간접 참조하는 것이 좋다.

식별자를 통한 어그리게잇 간 참조
그림 4 식별자를 통한 어그리게잇 간 참조

각 어그리게잇은 각각의 단일 트랜잭션으로 일관성을 유지하지하지만 다른 어그리게잇간과의 일관성이 필요하다면 어떻게 일관성을 유지하게 할 수 있을까? 위에 언급한 컨텍스트 간에 적용했던 도메인 이벤트를 사용하는 방식과 같다. 아래 그림과 같이 도메인이벤트를 통한 결과적 일관성을 사용해 다른 애그리게잇을 갱신하여 일관성을 유지한다.

결과적 일관성을 통한 어그리게잇 간 갱신

이렇게 DDD에서는 명확한 클래스의 유형과 어그리게잇 단위 식별을 통해 도메인 모델을 간결하고 단순하게 유지 하는 것을 추구한다.

도메인 이벤트

도메인 이벤트는 DDD 및 이벤트 스토밍에 말하는 도메인 이벤트의 구현 객체이다. 서비스 간 정합성을 일치시키기 위해 단위 어그리게잇의 주요 상태 값을 담아 전달되도록 모델링한다.

아래 그림을 보면 주문 서비스에서는 주문 트랜잭션 처리를 통해 주문엔티티와 주문아이템이 생성되어 저장됨과 동시에 주문됨 이벤트를 발행한다. 주문됨 이벤트에서는 주문됨 상태를 나타내는 주요 주문정보들을 포함하고 있다.

아래 예처럼 이벤트 발행은 주문 처리를 수행하는 트랜잭션과 묶어서 실행되어야 한다. 이벤트는 메시지 메커니즘을 통해 다른 서비스에 전달되게 되며 이를 통해 배송서비스는 배송 처리를 수행 할 수 있다.

도메인 이벤트 발행 예시
그림 5 도메인 이벤트 발행 예시

Summary

6회에 걸쳐 마이크로서비스 모델링에 대해 알아봤는데 정리하면 다음과 같다.

마이크로서비스 모델링의 주요 활동은 마이크로서비스를 도출하고 그 도출된 마이크로서비스를 상세하게 설계하는 것으로 나눠진다. 마이크로서비스 도출은 비지니스 능력기반으로 도출하는 방식과 DDD의 전략적 설계 방식을 이용하여 도출할 수 있다.

DDD의 전략적 설계의 개념과 구성요소들을 살펴보았고 전략적 설계를 쉽게 가속화 할 수 있는 워크샵방식인 이벤트 스토밍에 대해 살펴봤다.

이벤트 스토밍은 전통적인 방식에서 오랜 기간동안 수행했던 비지니스 분석, 이해관계자 의견개진, 공유, 리스크 도출 등을 가속화하여 진행하는 협업,공유,의사소통에 최적화된 설계방식이다. 애자일 프로세스 같이 급변하는 비즈니스에 빠른 대응을 하기 위해서는 지속적인 공유, 신속한 의사소통 ,빠른 피드백이 필요하다. 이걸 가능케 하는 설계 기법이 이벤트 스토밍이다.

이벤트 스토밍을 통해 마이크로서비스를 도출하면 각 마이크로서비스의 세부 설계를 진행할 수 있다. 세부적인 설계로 들어가서 프론트엔드 설계의 고려사항을 살폈고, 백엔드 설계에서 유연한 헥사고널 아키텍처를 가능케 해주느 도메인 모델링에 대해서도 자세히 살펴봤다.

도메인 모델링은 DDD의 전술적 설계 구성요소를 위해 비지니스 도메인 모델을 쉽고 단순하게 구성하게 해준다.