도메인 주도 개발 시작하기: 9. 도메인 모델과 바운디드 컨텍스트

ParkIsComing·2023년 4월 3일
0

이 책을 읽으면서 한번은 나오겠지 싶었던 MSA가 이 챕터에서 언급되었다.
매우 짧게 언급되었지만, 이번 포스팅에서는 MSA와 DDD를 연관지어 넓고 얕게 다뤄보려 한다.
(이벤트 관련 내용은 다음 챕터에서 등장하기 때문에 따로 언급하지 않는다.)

MSA란?

☑️ Monolithic : 모든 서비스를 하나의 애플리케이션에 구현(db도 공유)
☑️ MSA(Micro Service Architecture) : 분리될 수 있는 비즈니스 요소는 마이크로서비스 단위로 DB까지 나누고 이들이 모여 하나의 서비스를 구성하게 됨.
-> 결론적으로 마이크로서비스는 각각의 저장소를 독립적으로 보유하며 각 데이터는 다른 서비스의 직접 참조가 되어서는 안 됨

비유하자면 이렇다.

MSA의 장점

  • 집중할 필요가 있는 곳(예: 트래픽이 몰리는 곳)에 리소스를 더 할당하는 식으로 효율적인 리소스 사용이 가능
  • 도메인 간의 결합도가 약함 -> 특정 마이크로 서비스에서 장애가 발생해도 다른 마이크로 서비스에는 적은 영향을 미치면서 복구할 수 있다.
  • 높은 개발 유연성 : 마이크로 서비스별로 다른 언어를 사용할 수도 있고, 다른 환경세팅 하에 개발할 수도 있다.

MSA의 단점

  • 시스템이 복잡하면 복잡할수록 MSA에 빛을 발한다. 달리 말해 규모가 크지 않는 프로젝트라면 굳이 필요하지 않다는 의견도 있다.(feat. 마틴 파울러..)

그렇지만 많은 IT 기업에서는 MSA를 채택하고, 적용하고 있다.

배달의 민족도 오랜시간에 걸쳐 모놀리틱에서 MSA로의 전환을 완료했다. (김영한님이 나오셔서 이 주제로 세션을 진행하시기도 했다..)

결론적으로 오늘날에는 MSA를 빼놓고는 서비스 아키텍처를 논하기 어려울 것 같다.

MSA와 DDD의 연결점: 바운디드 컨텍스트

결국 잘게 쪼갠다는 것이 MSA의 본질이다.
그럼 여기서 문제가 생긴다. 무슨 기준으로 쪼갤 것인가?

MSA가 빛을 발하려면 마이크로 서비스 간의 느슨한 결합 & 높은 응집성을 지키면서 잘 나눠야 한다.

이때 DDD의 바운디드 컨텍스트 개념을 도입한다.

바운디드 컨텍스트란?

  • 도메인 모델별로 사용하는 언어가 다른 경계가 생긴다.
  • 같은 이름이라도 의미하는 바가 다를 수 있다.
    • 카탈로그에서 상품은 상품 이미지, 상품명, 상품 가격, 상세 설명 같은 상품 정보가 위주이다..
    • 재고 관리에서는 실존하는 개별 객체를 추적하기 위한 상품이다.
  • 같은 존재를 도메인에 따라 다른 용어로 표현하기도 한다.
    시스템 사용자를 예로 들어보자.
    • 회원도메인에서는 '회원'
    • 배송 도메인에서는 '보내는 사람'
    • 주문 도메인에서는 '주문자'로 사용하는 언어가 다르다.
  • 바운디드 컨텍스트는 모델의 경계를 결정하며 한 개의 바운디드 컨텍스트는 논리적으로 한 개의 모델을 갖는다.
  • 각각의 바운디드 컨텍스트는 내부적으로 응집성이 높고 & 다른 바운디드 컨텍스트와 의존관계가 낮아야 한다.

이러한 바운디드 컨텍스트를 기반으로 마이크로 서비스를 도출해낼 수 있다.
바운디드 컨텍스트는 모델의 경계를 형성하기 때문에 바운디드 컨텍스트를 마이크로 서비스로 구현한다.

바운디드 컨텍스트의 구현

  • 모든 바운디드 컨텍스트를 도메인 주도로 개발할 필요는 없다.
  • 한 바운디드 컨텍스트에 두 방식을 혼합하여 사용할 수도 있다.
    • 예시) CQRS 패턴 (상태를 변경하는 명령 기능과 조회하는 쿼리 기능을 구분)
    • 상태 변경과 관련된 기능은 도메인 모델 기반으로 구현 + 조회 기능은 서비스 DAO를 이용하여 구현
  • 각 바운디드 컨텍스트는 서로 다른 구현 기술을 사용할 수도 있다.
    예시) 어떤 바운디드 컨텍스트에서는 레포지토리 구현 기술로 JPA/Hibernate를 사용하고
    다른 바운디드 컨텍스트에서는 레포지토리 구현 기술로 마이바티스를 사용하는 식으로
    바운디드 컨텍스트별로 적합한 구현 기술을 채택할 수 있다.
  • 바운디드 컨텍스트는 UI를 갖지 않을 수도 있다. (UI 서버를 파사드로 둘 수도 있다.)

    Facade Layer : 프레젠테이션 계층과 도메인 모델 계층 간의 논리적 의존성 분리

바운디드 컨텍스트의 통합

두 팀이 관련된 바운디드 컨텍스트를 개발하면 자연스럽게 두 바운디드 컨텍스트 간 통합이 발생한다.

두 바운디드 컨텍스트를 통합하는 방법은 다음과 같다.

    1. REST API 호출을 통한 직접 통합
    1. 메시지 큐를 이용한 간접 통합
    • 대표적인 방식은 메시지 큐를 사용하는 것
    • 메시지 큐는 비동기로 메시지를 처리한다.
    • 특정 바운디드 컨텍스트가 메시지를 큐에 추가하면 다른 컨텍스트가 큐에서 메시지를 가져와 처리한다.

바운디드 컨텍스트 간의 관계

앞서 각각의 바운디드 컨텍스트는 다른 컨텍스트 경계와 의존관계가 낮아야 한다고 했다. 그러나 바운디드 컨텍스트 간에 아무런 관계도 없는 것은 아니다.

1. 고객/공급자 관계

  • 상류 컴포넌트는 서비스 공급자 역할
  • 하류 컴포넌트는 서비스를 사용하는 고객 역할
  • 상류 컴포넌트는 하류 컴포넌트가 사용할 수 있는 통신 프로토콜을 정의하고 이를 공개한다.
  • 예시) 하류 컴포넌트의 카탈로그 컨텍스트는 추천 상품을 보여주기 위해 상류 컴포넌트인 추천 컨텍스트가 제공하는 REST API를 호출한다.

2. 공개 호스트 서비스(OHS)

  • 공개 호스트 서비스로 바운디드 컨텍스트에 대한 접근을 제공하는 프로토콜이나 인터페이스를 정의한다.
  • 하류가 사용할 수 있도록 서비스 형태로 공개된다.

3. 안티코럽션 계층(ACL)

  • 하류 컴포넌트는 상류 서비스의 모델이 자신의 도메인 모델에 영향을 주지 않도록 보호하는 완충 지대를 만들어야 한다.
  • 이 계층에서 두 바운디드 컨텍스트 간의 모델 변환을 처리한다.
  • 달리 말하자면, 하류 팀의 고유 모델을 지키기 위한 번역 계층이다. 상류,하류 컴포넌트 사이의 차이를 번역하며 하류 모델의 독립성을 유지시킨다.

4. 공유 커널

  • 바운디드 컨텍스트들끼리 공유하는 모델
  • 장점 : 같은 모델을 여러번 개발하는 중복을 줄인다.
  • 단점 : 한 팀에서 임의로 모델을 변경하면 안 되기 때문에 모델을 공유하는 두 팀이 밀접한 관계를 형성할 수 없다면 개발이 지연될 수 있다.

5. 독립 방식

  • 두 바운디드 컨텍스트 간에 통합하지 않고 독립적으로 모델을 발전시키는 방식
  • 이때 바운디드 컨텍스트 간의 통합은 수동으로 진행한다.
  • 규모가 커질수록 수동 통합에도 한계가 있다. 이때는 두 바운디드 컨텍스트를 통합해야 한다. 두 바운디드 컨텍스트를 통합해주는 별도의 시스템이 필요할 수도 있다.

컨텍스트 맵

지금까지 바운디드 컨텍스트가 무엇인지, 바운디드 컨텍스트 간의 관계로는 무엇이 있는지에 대해 알아봤다.

이제는 최종적으로 컨텍스트 맵을 도출해보자. 컨텍스트 맵은 식별된 마이크로 서비스와 그들간의 의존관계를 보여준다.

아래 그림이 컨텍스트 맵의 예시이다. 상류 컨텍스트에서 OHS(오픈 호스트 서비스)를 발행하면, 하류 컨텍스트에서 ACL(안티코럽션 계층)을 통해 하류 콘텍스트에 맞게 모델을 변환하여 사용한다.

참고 자료

Do Not Use MSA - 마이크로서비스 아키텍처가 꼭 필요한가요?https://www.samsungsds.com/kr/insights/msa.html
SK(주) C&C's TECH BLOG : 마이크로서비스 모델링 시리즈
https://engineering-skcc.github.io/agile/microservice-agile/
[우아콘2020] 배달의민족 마이크로서비스 여행기
https://www.youtube.com/watch?v=BnS6343GTkY

0개의 댓글