최범균 님의 "도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지" 책을 정리한 포스팅 입니다.
1. 시스템 간 강결합 문제
- 바운디드 컨텍스트들 간의 강결합
- ✅ 외부 시스템을 호출하는 서비스가 도메인 로직에 결합하는 경우를 말함
문제점
문제점 | 설명 |
트랜잭션 처리 애매함 |
외부 서비스 실패 시 롤백 or 상태 변경 여부가 불명확함
|
성능 병목 |
외부 API 지연이 전체 시스템 응답 시간에 영향
|
도메인-외부 로직 혼합 |
도메인 객체가 외부 호출을 직접 다루면 유지보수 어려움
|
해결 방법
- 비동기 이벤트 기반 처리로 결합도 낮추기
2. 이벤트
- 과거에 일어난 일
- ✅ 상태 변화의 후속 처리를 트리거하는 역할
- ➡️ 도메인의 상태 변경과 관련된 요구사항을 이벤트를 이용해서 구현할 수 있음
구성
- 종류: 클래스 이름으로 표현
- 발생 시간
- 추가 데이터: 이벤트와 관련된 정보 (핸들러가 처리하는데 필요한 정보)
용도
용도 | 설명 |
트리거용 |
도메인 상태 변경 → 외부 처리 시작 (ex. 결제 완료 → 배송 시작)
|
데이터 동기화용 |
시스템 간 DB/상태 동기화 등
|
구성요소
구성요소 | 설명 | 특징 / 예 |
이벤트 생성 주체 | 엔티티, 밸류 객체 | 도메인 메서드를 통해 상태가 바뀌면 관련 이벤트를 발생시킴 |
이벤트 디스패처 |
이벤트를 적절한 핸들러로 전달
|
ex) Spring의 ApplicationEventPublisher
|
이벤트 핸들러 |
이벤트 수신 후 필요한 처리를 수행
|
ex) @EventListener |
장점
- 유지보수성, 가독성 (서로 다른 도메인 로직이 섞이는 것 방지)
- 확장성
3. 이벤트, 핸들러, 디스패처 구현
이벤트 클래스
- 이벤트 표현
- ✅ 접미사 Event 사용
- ✅ 과거 시제 사용
Events 클래스와 ApplicationEventPublisher
- ApplicationEventPublisher: 스프링에서 제공하는 이벤트 디스패처
이벤트 발생과 이벤트 핸들러
- @EventListener: 이벤트 리스너 정의
흐름 정리
- 도메인: 도메인 로직 실행
- ApplicationEventPublisher: 도메인 이벤트 발생
- @EventListener: 도메인 이벤트 리스닝 (핸들러를 이용하여 처리)
4. 동기 이벤트 처리 문제
문제 | 설명 |
성능 저하 |
외부 호출 실패 시 전체 트랜잭션 지연/실패 가능
|
롤백 불확실성 |
외부 시스템 실패가 DB 롤백 조건인가? → 설계 고민 필요 (이벤트 행의 상태를 변경하는 방향이 있음)
|
5. 비동기 이벤트 처리
- 인과적 일관성만 보장되면 되는 경우가 많음
- 후속조치 실패 시
- ✅ 일정 간격으로 재시도하거나 수동 처리해도 되는 요구사항도 다수 있음
- ✅ 사용자에게 재시도 요청을 받는 요구사항도 존재함
로컬 핸들러 비동기 실행
- @Async 사용
- ✅ 이벤트 핸들러를 별도 스레드로 실행
메시징 시스템을 이용한 비동기 구현
과정
이벤트를 메시지 큐에 보냄
메시지 큐는 이벤트를 메시지 리스너에 전달
메시지 리스너는 알맞은 이벤트 핸들러를 이용해 이벤트를 처리함
이벤트를 메시지 큐에 저장하는 과정과 메시지 큐에서 이벤트를 읽어와 처리하는 과정은 별도 스레드나 프로세스로 처리됨
이벤트를 발생시킨 도메인 기능을 DB에 반영하고 메시지 큐에 이벤트를 저장하는 절차를 한 트랜잭션으로 묶어야 함
서로 다른 이기종간의 트랜잭션을 한 트랜잭션으로 실행하려면 글로벌 트랜잭션이 필요
글로벌 트랜잭션
장점: 안전하게 이벤트를 메시지 큐에 전달할 수 있음
단점: 전체 성능이 떨어짐. 지원하지 않는 메시지 큐도 존재함
특징
이벤트 발생 JVM과 이벤트 처리 JVM이 다름
이벤트 저장소를 이용한 비동기 처리
- 이벤트를 DB에 저장한 뒤에 별도 프로그램을 통해 이벤트 핸들러에 전달
- 이벤트 포워더는 주기적으로 이벤트 저장소에서 이벤트를 가져와 이벤트 핸들러를 실행함
장점: 이벤트 핸들러가 처리에 실패할 경우 다시 처리 가능
6. 이벤트 적용 시 추가 고려 사항
이벤트 소스를 EventEntry에 추가할 지 여부
포워더에서 전송 실패를 얼마나 허용할 것인가 (재시도 정책 필요)
이벤트 손실: 아웃박스 패턴 필요
이벤트 처리와 DB 트랜잭션 고려
'Code' 카테고리의 다른 글
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 2. 개략적인 규모 추정 (3) | 2025.08.01 |
---|---|
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 1. 사용자 수에 따른 규모 확장성 (2) | 2025.07.31 |
[도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지] 9. 도메인 모델과 바운디드 컨텍스트 (0) | 2025.06.20 |
[도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지] 8. 애그리거트 트랜잭션 관리 (0) | 2025.06.19 |
[도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지] 7. 도메인 서비스 (0) | 2025.06.19 |