Dev/SW Engineering

[Lecture] DDD 기반 MSA 모델링 - Intro, Strategic Design, Event Storming

HJChung 2023. 5. 31. 20:05

Intro

5월 21일 부터 31일 까지 약 10일간 인프런의 <도메인 주도 설계(DDD) 기반 마이크로서비스(MSA) 모델링> 강의를 들으며 도메인 주도 설계(Domain-Driven Design; DDD) 에 대해서 배웠다.

이를 하게 된 계기는

 

  • 내가 근무하고 있는 의료 인공지능 회사인 Deep Bio는 ‘의료’, ‘AI’ 라는 복잡하고 전문적이 도메인의 비즈니스 문제를 의료 인공지능 소프트웨어로 해결하고자 한다. 따라서 도메인을 이해하는 것이 개발의 첫 걸음인 경우가 많다. 실제로 종종 사내 Medical Officer님께서 병리에 대한 생물학적 도메인 지식의 강의를 해주시기도 한다.
  • 또한 AI ML 알고리즘을 구현하시는 연구팀, 실제 제품 개발을 담당하는 디자이너, 개발팀, 의료 도메인 전문가이신 Medical Officer, 의사분들, BD팀 등 많은 사람들의 협력으로 개발되는 소프트웨어이기 때문에 개발적인 부분에 대한 의사소통시에 가끔 괴리나 한계를 느끼곤 한다. 이는 생산성 저하로 이어진다.
  • Deep Bio 의 의료 병리 진단 서비스의 백엔드는 복잡하며 MSA 형태로 되어있다. 그리고 요즘 점점 다양한 서비스가 새로 개발되고, 여러 직의 변경사항이 생기고 있다. DDD는 자칫 복잡해질 수 있는 MSA설계를 agile하게 가져가는 방법론이라고 한다.
  • 그리고 CAO(Chief Architect Officer)님께서 DDD의 학습 및 적용을 적극 권장하심에 따라 사내 DDD 스터디가 생겼고, 이 스터디르 하기 전 미리 예습하는 것 삼아 강의를 들었다.

 

아래 정리한 내용은 미래에 빠르게 참고할 수 있도록 블로그 포스트 형식으로 <도메인 주도 설계(DDD) 기반 마이크로서비스(MSA) 모델링> 강의 내용을 요약하여 작성한 것이다. 또한 이 글을 읽은 누군가가 DDD와 MSA 모델링에 대해 관심이 생기거나 도움을 받을 수 있었으면 좋겠다.

 

해당 강의는

  • Section1: 마이크로서비스 개념
  • Section2: 마이크로서비스 개발프로세스
  • Section3: 도메인 주도 설계의 전략적 설계(Strategic Design) 이해
  • Section4: 전략적 설계 기법 - 이벤트 스토밍
  • Section5: 도메인 주도 설계의 전술적 설계(Tactical Design) 이해
  • Section6: 마이크로 서비스 아키텍쳐 패턴
  • Section7, 8: 실습 (Applying Domain-Driven Design in Practice)
  • Section9: 설계의사결정 및 구현과정 소개

로 구성되어 있다.


1. 마이크로서비스 개발 프로세스 (Section1, 2)

MSA 개발 프로세스 - MSA 개발에는 Agile process 방법론을 가장 많이 사용함.

MSA를 왜 도메인 주도 설계를 통해 풀어나가는 것이 적절한가

MSA로 아키텍쳐를 가져가고자 할 때 고려사항에는 아래의 것들이 있다.

  • 도메인:업무영역,제공서비스
  • 구성원역량,운영조직구조
  • 서비스 변경/배포 빈도
  • 사용량 : 트랜잭션 빈도
  • 데이터베이스 주제 영역 / 오너쉽

 

이런 것들이 있지만 결국 가장 중요한 것은 ‘비지니스’ 상에서 응집도는 높고 결합도는 낮게 도출하는 것이 가장 중요하다. 이렇게 도출 하도록 도와주는 설계 방법이 DDD이다.

DDD가 뭐길래?? 앞으로의 전체 강의에서 이것에 대해 배운다.

 

도메인 주도 설계(Domain-Driven Design; DDD) 란

도메인 주도 설계란, 이 강의를 통해 이해한 바대로 정리하자면

 

  • 엔지니어(개발자, 기획자, 디자이너, 도메인 전문가.... 등 문제를 소프트웨어 개발을 통해 해결하고자 하는 사람들 (이하 엔지니어))가 하는 일은 어떤 비즈니스적 문제(전략, 가치..)를 소프트웨어를 구축함으로서 해결하는 것이다.
  • 그렇기 때문에 우리 엔지니어들은 그 비즈니스적 문제가 뭔지 이해해야한다.
  • 그러기 위해서는 그 비즈니스 도메인을 이해해야 한다. 비즈니스 도메인이란 이 비즈니스의 주요 활동 영역을 말한다. 즉, 다시말해, 이 비즈니스 문제가 존재하는 맥락을 이해해야 하는 것이다.
  • 이러한 비즈니스 도메인을 더 세분화 해서 나눈 것이 하위 도메인(sub domain)이며 이는 곧 소프트웨어를 제공하는 서비스 단위가 될 수 있다.
  • 따라서 도메인 주도 설계란 우리의 소프트웨어가 해결할 비즈니스 문제의 도메인을 이해하고, 이에 맞게 설계하여 개발하는 설계 방법이다.

2. 도메인 주도 설계의 전략적 설계(Strategic Design) (Section3)

MSA와 DDD Strategic Design

MSA에서 마이크로서비스를 구분할 때

  • 비즈니스 응집성은 높이고
  • 결합도는 낮추는 것이 중요하다.

DDD를 통해 위 두 가지를 전략적으로 설계(이하 Strategic Design) 하기 위한 방법 중 하나가 <이벤트 스토밍> 이다.

전략적 설계라는 것은 비즈니스 도메인에 대해 추상화 단계를 높어서(hight-level view) 소프트웨어 아키텍쳐 설계를 고민하는 방법이다.

 

따라서 이 챕터를 읽으면서 놓지 않아야 할 가장 대표적인 질문, 학습 목표는 '도메인 주도 설계의 전략적 설계 방법을 통해 내가 문제를 해결하고자 하는 도메인(이하 '우리 도메인') 의 마이크로 서비스 설계를 어떻게 할 수 있을까?' 이다.

그리고 그에 따른 하위 질문은

 

  1. 마이크로서비스를 어떤 기준으로 분리할 것인가?
    1. 우리 도메인에서 Bounded Context는 어떻게 구분되는가?
    2. 우리 도메인의 Ubiquitous Language는 어떻제 정하는 것이 좋을까? → 카카오 용어집 언급 및 링크 달기.
  2. 마이크로서비스 간은 어떻게 연계할 것인가?
    1. 우리 도메인에서 Context Mapping은 어떻게 되는가?
  3. 어떤 이벤트에 의해 마이크로서비스가 서로 반응하는가?
    1. 우리 도메인에서 Domain Event는 무엇이 있고, 이 event에 연관된 것은 무엇이 있는가?

 

Sub Domain

우선 Strategic Design에 필요한 용어의 개념들을 소개한다.

앞서 잠깐 소개했듯이 비즈니스 도메인은 하위 도메인으로 세분화 할 수 있으며 하위 도메인의 아래 3 가지 타입으로 구분 할 수 있다.

 

  • 핵심(Core) : 비즈니스 경쟁사와 차별성 있는 기술력으로 경쟁력 있는 우리 기업만의 활동 영역. 우리 기업만의 서비스. 따라서 복잡성이 높을 수 있지만 경쟁 우위를 제공
    • ex. AI 의료 소프트웨어의 암진단 머신러닝 알고리즘과 모델 서빙 서비스, 우버의 방향에 따른 손님 매칭 서비스, 구글의 검색 순위 알고리즘.
    • 사내에서 구현되는 것이고 따라서 사내 조직의 핵심 숙련 인재가 할당되어 구현하곤 한다.
    • 가장 진보된 엔지니어링 기술 적용될 것이며 자주 지속적으로 변경이 예상되는 부분이다.
  • 일반(Generic): 모든 회사가 동일하게 수행하는 작업. 일반적인 문제들은 이미 다른 공급업체로부터 구입할 수 있는 완제품 소프트웨어에 의해 해결하거나 구현되어있으므로 가져다 쓰면 됨.
    • ex. 로그인 인증, 권한 부여 로직 등
    • 이미 만들어진 제품을 끼워 사용하거나
    • 오픈 소스 솔루션 사용
  • 지원(Supporting) : 간단한 기능이며 그 자체로 경쟁 우위를 제공하지는 않는 것., 여전히 비즈니스의 핵심 업무를 지원하므로 소프트웨어를 내부에서 개발.
    • ex. CRUD api
    • 사내에서 개발해도 되고, 위부에서 개발해줘도 됨.
    • 새로운 인재 양성을 위한 연습 기회 제공

           

term ubiquitous language

유비쿼터스 언어란 도메인을 설명하기 위한 단일화된, 정확하고 일관성 있는 언어(체계) 이다.

이게 필요한 이유는 도메인을 분석하고, 설계할 때 사용한 언어와 실제 코드로 구현되었을때의 용어가 다르면, 기존의 과정에서는 변환의 과정을 거치게 되어 도메인 언어가 기술 언어로 변환되면서 괴리가 생기기 때문이다.

이는 도메인 전문가(예를 들어 병리 진단 AI 의료 소프트웨어 같은 경우 병리 의사)와 실제 소프트웨어 개발자 사이에 사용하는 언어가 달라지고,

실제 사용자가 ‘될 수도 있는’ 도메인 전문가가 문제를 이해하는 방식과의 괴리로 이어질 가능성이 있다.

따라서 유비쿼터스 언어를 정하고, 이에 맞게 그대로 코드로 작성하는 것이 유용하다.

 

Domain model

엔지니어는 문제를 해결하는 소프트웨어에 구현되어야 할 명사와 행위를 파악한다. 이렇게 파악된 명사화 행위, 특정 도메인을 개념적으로 표현한 것을 Domain model이라고 한다.

나는 ‘문제 해결의 추상화 단위를 높여서 기획하는 것’ 이라고 이해했다. 결국 OOP 의 가치관과 연결되는 듯 하다. <객체지향의 사실과 오해> 를 읽었던 게 생각이 어렴풋이 났는데, 다시 좀 찾아봐야겠다.

이제 Domain modeling, 즉, 유비쿼터스 언어로 사실상 비즈니스 도메인 모델을 구축하는 것을 할 차례이다.

Bounded Context

그런데..! (두둥탁) 서비스가 조금만 다양해져도 ubiquitous language는 비즈니스 전반에 걸쳐 일관성을 가지기가 어렵다.

예를 들어 보는 것이 더 와닿는다.

 

주문(Order) 서비스에서의 customer과 배송(Delivery) 서비스에서의 customer과 고객관리(Accounting) 서비스에서의 Customer의 의미가 다르다. 다시말해 주문의 유비쿼터스 언어들과 고객의 유비쿼터스 언어들이 다르기때문에 이를 도메인 지식을 경계로 구분할 필요가 있다. 이 ‘경계’를 bounded context라고 한다.

 

여기서 주의 할 것! Bounded Context와 Sub Domain 차이?!

Sub domain은 비지니스 전략에 의해 정의됨. 반면에 Bounded Context는 소프트웨어 엔지니어에 의해 설계됨. Sub domain은 발견되고 Bounded Context는 설계한다는 점

 

Context Mapping

Bounded context는 서로 독립적으로 발전할 수 있지만 상호작용해야 한다. 즉 각 Bounded Context는 접점이 있다.

Context Mapping에는

 

  • Partnership: Teams working on two bounded contexts notify each other about changes in a completely ad-hoc manner.
  • Shared Kernel: Two bounded contexts agree on a common subset of a model and closely collaborate while changing it.
  • Conformist: A consumer bounded context conforms to the model by a producer bounded context.
  • Anticorruption Layer: A consumer bounded context puts in place protection mechanisms in order to protect itself from any breaking changes in a producer bounded context.
  • Open-host Service: A producer bounded context puts in place protection mechanisms in order to protect its consumers from any breaking changes it might cause internally.
  • Separate Ways: Two teams working on two bounded contexts might decide that their collaboration is not worth it and therefore decide to duplicate models and functionalities independently.

 

이라는 패턴이 존재하고, (패턴 설명 출처: https://tonisoueid.medium.com/book-review-learning-domain-driven-design-by-vlad-khononov-c7473afa5ba) 이런 패턴에 입각해서 이해하면 좋다.

 


 

3. 전략적 설계(Strategic Design) 기법 - 이벤트 스토밍 (Section4)

이제 Strategic Design에 필요한 개념들을 모두 알아봤으니 DDD로 마이크로 서비스 설계를 실제 로 해보기 위한 방법인 이벤트 스토밍(Event Storming)을 알아본다.

이때 중요한 것은 앞서 짧게 ‘엔지니어’ 라고 칭한 사람들, 즉 이해 관계자. 개발자, 기획자, 디자이너, 도메인 전문가.... 등 문제를 소프트웨어 개발을 통해 해결하고자 하는 사람들 이 모두 모여서 이벤트 스토밍을 함께 진행해야 한다는 것이다.

 

이벤트 스토밍 구성 요소

 

아래는 이커머스 소프트웨어를 만들기 위한 이커머스 도메인을 바탕으로 진행한 이벤트 스토밍 예시 그림이다.

여기엔 명시적으로 작성하지 못했지만 강의에서는 <개발요구사항 명세서> 와 같은 문서를 통해 요구사항을 파악하고, 거기서 유비쿼터스 언어를 1차적으로 생각한 다음, 이벤트 스토밍을 진행하면서 용어를 점점 다듬고, 통일해 나가셨던 것으로 기억한다.

원형으로 경계 지어진 것은 bounded context이다.

 

아래는 context mapping을 진행한 결과이다.

 


마치며

여기까지

위 이벤트 스토밍 과정을 통해서 각 micro service의 business logic에 영향을 주는 것들 (API 후보인 Command, data 요소인 Aggregate, 서비스에서 발생하는 주요 이벤트인 Domain Event .. 등) 이 도출되었다.

이제 이 서비스를 개발 해야하는 단계이고, 이 때 하는 것이 전술적 설계(Tactical Design)이다.

비즈니스 로직 구현시 Tactical Design을 할 때 표현 방법에 여러 패턴이 있고, 이 패턴들을 알아보는 것이다.

이에 대해 강의에서 배운 내용은 다음 블로그 글에서 정리하고자 한다.

 

도움 받은 글

DDD 에 관한 책

스터디에서 공유받은 자료

우아한 형제들 DDD 스터디 소개 글