[DDD START] 10장 이벤트

David Lee·2023년 12월 21일
0

DDD Start

목록 보기
10/12
post-thumbnail

이 포스트는 📔 도메인 주도 개발 시작하기 책을 읽고 공부한 내용을 정리한 포스트입니다.

10장. 이벤트

10.1 시스템 간 강결합 문제

외부 시스템을 활용하는 트랜젝션에서 외부 시스템의 오류가 발생한다면 트랜잭션을 롤백해야할까? 커밋해야할까?
트랜잭션을 롤백하는 것도 방법일 수 있고, 커밋 이후 외부 시스템의 오류가 수정된다면 다시 시도하도록 구현하는 것도 방법일 수 있다.
하지만 이런 식의 해결책은 정확한 방법이라고 하기 어렵다. 시스템 간 강결합에 의해 한 시스템의 오류가 다른 시스템에도 영향을 끼친다는 것은 개발과정에서 어려움을 야기한다.
그렇다면 시스템 간 강결합을 어떻게 없앨 수 있을까? 답은 이벤트에서 살펴볼 수 있다.

10.2 이벤트 개요

이벤트는 '과거에 발생한 어떤 사건'을 의미한다. 예를 들어 사용자 A 가 사용자 B에게 메시지를 남겼다면 '메시지를 전송함' 이벤트가 벌어졌다고 볼 수 있다.

도메인 모델에 이벤트를 도입하기 위해서는 이벤트, 이벤트 생성 주체, 이벤트 디스패처, 이벤트 핸들러 4개의 구성요소가 필요하다.

도메인 모델에서 이벤트 생성 주체도메인 객체이다. 도메인 객체에서 상태 변경 로직이 실행되면 관련 이벤트가 발생한다.

이벤트 핸들러는 생성 주체가 발생한 이벤트에 반응해서 이벤트를 전달받아 이벤트가 원하는 기능을 실행 시킨다.

그렇다면 이벤트 생성 주체와 이벤트 핸들러는 누가 연결해줄까? 바로 이벤트 디스패처다. 이벤트 생성 주체가 이벤트를 생성하여 이벤트 디스패처에게 전달하면, 이를 전달받은 디스패처는 해당 이벤트를 처리할 수 있는 핸들러에게 이벤트를 전달한다.

그렇다면 이벤트는 어떻게 구성될까? 이벤트는 아래와 같이 구성된다.

  • 이벤트 종류
  • 이벤트 발생 시간
  • 이벤트 관련 정보 추가 데이터

이벤트의 용도는 크게 두가지로 나눌 수 있다.

  • 트리거(Trigger)
    • 도메인의 상태 변화에 따른 후처리 트리거로써 이벤트를 사용할 수 있다.
  • 동기화(Sync)
    • 하나의 시스템에서 변경된 정보를 연관된 시스템에서 동기화 할 수 있다.

결국 이벤트를 적용함으로써 시스템 간 강결합 문제를 해결할 수 있고, 강결합 문제를 해결함으로써 추가적이 기능 확장에서의 용이함을 가져갈 수 있다.

10.3 이벤트, 핸들러, 디스패처 구현

이벤트는 Spring에서 제공하는 ApplicationEventPublisher를 이용해서 생성 가능하며, ApplicationEventPublisher@EventListener 어노테이션이 붙은 메서드를 찾아서 이벤트를 핸들링한다.

이벤트는 응용 서비스와 동일한 트랜잭션 범위에서 이벤트 핸들러에 의해 실행된다.

10.4 동기 이벤트 처리 문제

강결합 문제는 해결됬지만 이벤트에서 외부 서비스를 처리할 때 외부 서비스에 오류나 성능 저하가 발생하면 어떻게 될까? 이 부분에서도 문제가 생긴다. 트랜잭션을 롤백하거나 커밋하는 대신 나중에 다시 처리해주기라는 분기로 다시 돌아가게 되는데 이러한 성능이나 트랜잭션 범위 문제를 이벤트에서 해소하는 방법이 2가지 존재한다. 바로 비동기 처리방법과, 트랜잭션 연계 방법이다.

10.5 비동기 이벤트 처리 문제

처음에 예를 들었던 메시지를 떠올려보면 사용자 A가 사용자 B에게 메시지를 보내는 과정에서 메시지를 이메일로 바꿔본다면 사용자 A가 메일을 전송하자마자 B에게 전달될 필요는 없다. 어느정도 짧은 텀을 두고 도착해도 문제가 발생하지 않기 때문이다.

구현 과정에서 '메일을 일정시간 안에 전달하라'라는 요구사항을 '메일을 최대 *시간 안에 전달하라'로 바꾸게 된다면 전달에 대해서 비동기적인 처리 방법을 생각할 수 있게 된다.

이벤트를 비동기로 구현할 수 있는 방법은 아래와 같다.

  • 로컬 핸들러를 비동기로 실행하기
  • 메시지 큐 활용하기
  • 이벤트 저장소와 이벤트 포워더 사용하기
  • 이벤트 저장소와 이벤트 제공 API 사용하기
  • ...

10.6 이벤트 적용 시 추가 고려 사항

이벤트를 구현하는 과정에서 추가적으로 고려해야 할 점은 아래와 같다.

  • 이벤트 소스를 Entry에 추가할 것인가?
  • 포워더는 어느정도의 전송 실패를 허용해야 할까?
  • 이벤트가 손실되는 과정에 대한 처리는?
  • 이벤트의 순서는 어떻게 정해야 할까?
  • 이벤트를 재처리하는 과정은?

아래에 대한 고려를 충분히 진행하고 이에 맞는 이벤트 구현 방식이 필요하다.

이벤트를 구현하는 과정에서 트랜잭션은 빠질 수 없는데 이벤트 처리 결과와 트랜잭션의 커밋/롤백 여부를 함께 고려하면서 구현을 진행해야 한다.

profile
쌓아가기

0개의 댓글

관련 채용 정보