728x90
반응형
09. 커뮤니케이션 패턴
- 바운디드 컨텍스트 간 커뮤니케이션을 용이하게
- 애그리게이트 설계 원칙의 제한 사항 해결, 여러 시스템 컴포넌트에 걸쳐 비즈니스 프로세스 조율 역할
모델 변환
- 바운디드 컨텍스트 : 유비쿼터스 언어 모델의 경계
- 만약 다른 바운디드 컨텍스트가 협력할 의향이 있다면?
- 바운디드 컨텍스트를 파트너십을 통해 통합 가능 : 프로토콜 조정 및 팀간 커뮤니케이션으로 해결 가능
- 협력 기반 통합 방법 : 공유 커널 방법 사용 (제한된 부분을 공동으로 함께 발전시킴)
- 업스트림(제공자) / 다운스트림(사용자)
- 이 때 다운스트림이 업스트림의 바운디드 컨텍스트 모델을 따를 수 없을 때 처리 방법은 2가지
- 다운스트림 측에서 ACL(충돌방지계층) 사용하여 업스트림 모델을 조정하여 사용
- 업스트림 측에서 OHS(오픈호스트서비스) 역할을 통해 구현 모델에 대한 병경으로부터 사용자 보호
그렇다면 모델 변환 로직은?
Stateless 모델 변환
스테이트리스 모델 변환을 소유하는 바운디드 컨텍스트는 Proxy 디자인 패턴을 통해 모델 매핑처리
- 업스트림의 경우 : OHS(수신)
- 다운스트림의 경우 : ACL(발신)
만약 업스트림에서 힘이 없어서 업스트림에서 변환 처리 해줘야 하는 상황
- 다운스트림 -> (요청) -> Proxy(OHS) -> 업스트림
다운스트림에서 힘이 없어서 본인이 직접 변환 처리 해야해
- 다운스트림 <- (응답) <- Proxy(ACL) <- 업스트림
StateLess 방식의 동기/비동기 방식
동기
- OHS : 공용 언어로의 변환은 유입되는 요청을 처리할 때 발생
- ACL : 업스트림 바운디드 컨텍스트를 호출할 때 발생
- 경우에 따라 변환 로직을 API 게이트웨이 패턴과 같은 외부 컴포넌트로 넘기는 것이 효율적일 수 있음
- OHS 를 구현하는 바운디드 컨텍스트의 경우(업스트림) API게이트웨이는 내부 모델을 통합에 최적화된 공표 언어로 각각 다운스트림 별로 변환하는 역할 수행
- ACL 를 API게이트웨이 패턴을 사용하는 경우 어차피 다운스트림에서 순응하기 떄문에 ACL은 통합 관련 바운디드 컨텍스트 역할을 한다.
- 이처럼 바운디드 컨텍스트를 편리하게 모델 변환하는 역할을 하므로, 교환 컨텍스트라고도 명함
비동기
- OHS 구현시 비동기식 모델 변환은 반드시 필요
- 비동기 변환 사용시 도메인 이벤트를 가로채서 공표된 언어 변환할 수 있으므로 바운디드 컨텍스트의 구현상세를 더 잘 캡슐화할 수 있다(?)
- 메시지를 공표된 언어로 변환시 private event와 public event(다른 바운디드 컨텍스트 연동을 위한) 구분 가능
StateFull 모델 변환
- 데이터 집계(일괄 처리 / 이벤트 통합)시 사용
- 데이터 집계를 통한 모델 변환은 API 게이트 웨이를 사용하여 구현할 수 없음
- 따라서 들어오는 데이터 추적 및 처리에 대한 변환 로직에 대해 자체 영구 저장소가 필요함 (Proxy 에 별도 storage 필요)
- 요청 통합에 대한 방법
- BackEnd-for-frontEnd Pattern 사용 : 사용자 인터페이스가 여러 서비스에서 발생하는 데이터 결합
- ACL 을 바운디드 컨텍스트 전면에 배치하여 바운디드 컨텍스트 연동과 비즈니스 로직의 복잡성 분리 (ex_ 여러 다른 데이터 처리/복잡한 비즈니스 로직 구현해야하는 바운디드 컨텍스트)
애그리게이트 연동
- 애그리게이트에서 바로 도메인 이벤트 발행은 좋지 않음
-
- 애그리게이트의 새로운 상태가 DB에 커밋 전에 이벤트가 전달된다.
-
- 경합 조건 : 후속 애그리게이트 로직에 인해 작어비 무효화되거나 단순 DB 문제로 인해 Tx가 커밋되지 않을 수 있음
-
- 그렇다면 도메인 이벤트 발행 책임을 어플리케이션 계층으로 이전한다면 (인스턴스 로드 -> 갱신된 상태 DB 커밋 -> 이벤트 발행) 이라면 괜찮을까?
- 메시지 버스 다운 혹은 이벤트 발행 전 로직 다운 등의 이유로 일관성없을 수 있음
- 아웃박스 패턴을 사용해보자
아웃박스 패턴
도메인 이벤트의 안정적인 발행 보장
- 업데이트된 애그리게이트의 상태와 도메인 이벤트 모두 동일한 원자성 트랜잭션으로 커밋
- 메시지 릴레이는 DB에서 새로 커밋된 도메인 이벤트를 가져옴
- 릴레이는 도메인 이벤트를 메시지 버스에 발행
- 성공적으로 발행 시, 릴레이는 이벤트를 DB에 발행한 것으로 표시 / 삭제
- 다중 문서를 지원하지 않는 NoSQL은 전달된 도메인 이벤트는 애그리게이트 레코드에 포함되어야 함
발행되지 않은 이벤트 가져오기
Pull 방식 (발행자 폴링)
- 릴레이는 발행되지 않은 이벤트에 대해 DB를 지속해서 질의 가능
- 지속적인 폴링으로 인한 DB 부하를 최소화하기 위해서는 적절한 인덱스 필요
Push 방식(트랜잭션 로그 추적)
- DB 기능을 이용하여 새 이벤트가 추가될 떄마다 발행 릴레이를 호출 가능
- ex) DB 트랜잭션 로그를 추적하여 업데이트/삽입된 레코드에 대한 알림을 받을 수 있음
아웃박스 패턴은 적어도 한 번은 메시지 배달을 보장한다는 점 유의
- 메시지 발행한 후 릴레이가 실패했지만 DB에 발행한 것으로 표시하기 전에, 릴레이 실패한다면 다음 이터레이션에서 같은 메시지가 다시 발행
SAGA 패턴
- 핵심 애그리게이트 설계 원칙 중 하나 : 각 트랜잭션을 애그리게이트의 단일 인스턴스로 제한
- 애그리게이트의 경계를 신중하게 고려하고 응집된 비즈니스 기능 집합을 캡슐화 할 수 있음
- 하지만, 여러 애그리게이트에 걸쳐있는 비즈니스 프로세스를 구현해야 하는 경우가 있음
책임이 분리되어있는 바운디드 컨텍스트에 속할 수 있는 부념ㅇ히 다른 비즈니스 엔티티에 대해 다른 바운디드 컨텍스트에 속할 수 있는 분명히 다른 비즈니스 엔티티이기 때문이다.
- 이러한 흐름은 사가로 구현할 수 있다.
- 사가는 트랜잭션 측면에서 보는 것
- 즉, 여러 트랜잭션에 걸쳐 있는 비즈니스 프로세스
- 사가는 관련 컴포넌트에서 발생하는 이벤트를 수신, 다른 컴포넌트에 후속 커맨드를 실행
- 실행 단계 중 하나가 실패하면 사가는 시스템 상태를 일관되게 유지하도록 적절한 보상 조치를 내림
- 발행 프로세스를 구현하기 위해 사가는 Campaign 애그리게이트로부터 CampaignActivated Event, AdPublishing 바운디드 컨텍스트로부터 Publishing 이벤트를 기다린다.
- 이벤트를 전달하고 관련 커멘드를 실행하여 이벤트에 반응
- 사가는 상태 관리 필요의 유무에 따라 달라진다.
- 상태 관리가 필요한 경우 : 실행된 작업을 추적하여 실패 시 적절한 보상 조치를 실행할 수 있음
- 이러한 경우, 사가는 이벤트 소싱 애그리게이트로 구현하여 수신된 이벤트와 실행된 커멘드의 전체 기록 유지 가능
- 그러나 커맨드 실행 로직은 도메인 이벤트가 아웃박스 패턴으로 전달하는 방식과 유사하게 사가 패턴 자체에서 벗어나 비동기적으로 실행한다.
일관성
- 사가 패턴이 다중 컴포넌트의 트랜잭션을 조율하기는 하지만, 관련된 컴포넌트의 상태는 궁극적으로 일관성을 가짐
- 사가가 결국 관련 커맨드를 실행한다고 해도 두 개의 트랜잭션은 원자적으로 간주되지 않기 떄문에 모두 성공하거나 실패할 수 없다.
애그리게이트 경계 내의 데이터만 강한 일관성을 가진다. 외부의 모든 것은 궁극적으로 일관성을 갖는다.
- 이러한 부적절한 애그리게이트 경계를 보상하기 위해 사가를 남용하지 않는 지침을 따르는 것을 원칙으로 하자
- 동일한 애그리게이트에 속해야 하는 비즈니스 작업에는 강한 일관성을 갖는 데이터가 필요
프로세스 관리자 패턴
- 사가 패턴은 단순하고 선형적인 흐름을 관리 (사가는 이벤트를 해당 커멘드와 일치시킴)
- 구현 관점에서는 상태 기반 혹은 이벤트 소싱 애그리게이트로 구현
- 프로세스 관리자는 시퀀스의 상태를 유지하고 다음 처리 단계를 결정하는 중앙 처리 장치로 정의한다.
- 경험에 비추어 볼 때 사가에
if-else
문이 포함되어 있다면 아마도 프로세스 관리자일 것 - 프로세스 관리자와 사가의 차이점
- 사가는 특정 이벤트가 관찰될 떄 암시적으로 인스턴스화
- 프로세스 관리자 : 단일 소스 이벤트에 바인딩될 수 없음 (여러 단계로 구성된 응집된 비즈니스 프로세스) : 따라서 명시적으로 인스턴스화
- 출장 예약 프로세스를 트리거하는 중앙 엔티티가 없으며, 출장 예약은 프로세스 이기 때문에 프로세스 관리자로 구현
결론
- ACL, OHS 를 구현하는데 사용할 수 있는 모델 변환 패턴 (즉석 변환 혹은 상태 추적이 필요한 경우 좀 더 복잡한 로직으로 구현)
- 아웃박스 패턴 : 애그리게이트의 도메인 이벤트 발행하는 안정적인 방법 (다른 프로세스가 실패해도 도메인 이벤트 항상 발행)
- 사가 패턴 : 간단한 교차 컴포넌트 비즈니스 프로세스 구현에 사용
- 프로세스 관리자 패턴 : 좀 더 복잡한 비즈니스 프로세스 구현 가능
- 두 패턴 모두 도메인 이벤트에 대한 비동기식 반응과 커맨드 실행에 의존
728x90
반응형
'책 > 도메인 주도 설계 첫걸음' 카테고리의 다른 글
도메인 주도 설계 첫걸음 - 8장 : 아키텍처 패턴 (계층형 /CQRS / 포트와 어댑터) (0) | 2023.06.06 |
---|---|
도메인 주도 설계 첫걸음 - 7장 : 이벤트 소싱 (0) | 2023.04.22 |
도메인 주도 설계 첫걸음 - 6장 : 복잡한 비즈니스 로직 다루기 (0) | 2023.04.14 |
도메인 주도 설계 첫걸음 - 5장 : 간단한 비즈니스 로직 구현 (0) | 2023.04.14 |
도메인 주도 설계 첫걸음 - 3장, 4장 (0) | 2023.03.25 |