2. 주요 내용
❏ 이벤트의 용도와 장점
❏ 핸들러 디스패치와 핸들러 구현
❏ 비동기 이벤트 처리
3. 시스템 간 강결합 문제
❏ 쇼핑몰 구매 취소 시 환불 문제
❏ 주문 도메인에서 환불 기능을 실행
❏ 환불 도메인이 외부 시스템이라면
❏ 환불처리 과정에서 예외발생으로 구매취소 트랜잭션도 롤백해야 하는가…
❏ 외부 서비스 성능에 직접적인 영향을 받는다.
❏ 도메인 객체에 서비스를 전달하면
❏ 주문로직과 결재로직이 섞이는 문제
4. 시스템 간 강결합 문제를 해결하려면..
❏ 이벤트를 사용하여 구매시스템과 결재 시스템간 강결합 문제를 해결
❏ 이벤트를 사용하면 서로 다른 도메인이 섞이는 것을 방지할 수 있음
5. 이벤트 관련 구성요소
❏ 이벤트 생성 주체
❏ 이벤트 디스패처(퍼블리셔)
❏ 이벤트 핸들러
이벤트 생성 주체
이벤트 디스패쳐
이벤트 퍼블리셔
이벤트 핸들러
event event
6. 이벤트 구성
❏ 이벤트 종류
❏ 클래스 이름으로 이벤트 종류 표현
❏ 이벤트 발생시간
❏ 추가 데이터
❏ 주문번호, 신규 배송지 정보 등 이벤트와 관련된 정보
생성자
7. 이벤트 용도
❏ 트리거
❏ 시스템간의 데이터 동기화
Order EventDispatcher
OrderCanceled
EventHandler
OrderCanceled
event
OrderCanceled
event
RefundService
8. 이벤트, 이벤트 핸들러, 디스패처 구현
❏ 이벤트 클래스 (Event)
❏ 이벤트 핸들러 (EventHandler)
❏ 이벤트 핸들러의 상위 타입으로 모든 핸들러는 이 인터페이스를 구현한다.
❏ 디스패처 (Events)
❏ 이벤트 디스패처, 이벤트 발행, 이벤트 핸들러 등록, 이벤트를 핸들러에
등록하는 등의 기능을 제공
9. 이벤트 클래스
❏ 이벤트는 과거에 벌어진 상태 변화나 사건을 의미하므로 이벤트클래스의
이름을 결정할 때에는 과거 시제를 사용
❏ 접미사로 Event를 사용
❏ Event(s)
❏ OrderAcceptedEvent
❏ OrderCanceledEvent
❏ OrderShippedEvent
❏ CommentAddedEvent
❏ ReviewQuarantinedEvent
❏ ReviewUnquarantinedEvent
17. 동기 이벤트 처리 문제
❏ 시스템간 강결합은 해결했으나 외부시스템 성능 영향
환불처리가 느려진다면
18. 비동기 이벤트 처리
❏ ‘A하면 이어서 B하라’
❏ ‘A하면 최대 언제까지 B하라’로 바꿀수 있는 요구사항
❏ 비동기 이벤트 처리 방법
❏ 로컬 핸들러를 비동기로 실행
❏ 메시지 큐를 사용한 비동기 구현
❏ 이벤트 저장소와 이벤트 포워더 사용하기
❏ 이벤트 저장소와 이벤트 API 사용하기
19. 로컬 핸들러의 비동기 처리
❏ 이벤트 핸들러를 별도 스레드로 이벤트 핸들러를 비동기로 실행
executor.submit(() -> handler.handle(event));
20. 트랜잭션 범위
메시징 시스템을 이용한 비동기 구현
Order Events RabbitMQ
Events.raise rabbitTemplate.
convertAndSend()
Message
Listener
EventHandler
onMessage()
handle()
트랜잭션 범위
21. 이벤트 저장소와 이벤트 포워더 사용하기
❏ 이벤트를 일단 DB에 저장
❏ 포워더(별도 프로그램)를 이용 이벤트 핸들러에 이벤트 전달
도메인 이벤트 디스패처 로컬핸들러
포워더 이벤트핸들러
저장소
이벤트 저장
이벤트를 주기적으로 읽어와 전달
어디까지 전달했는지 추적
22. 이벤트 저장소와 이벤트 API 사용하기
❏ 이벤트를 일단 DB에 저장
❏ 외부핸들러가 API서버를 통해 이벤트 목록을 가져오는 방식
도메인 이벤트 디스패처 로컬핸들러
API 이벤트핸들러
저장소
이벤트 저장
API를 통해 이벤트를
읽어와 처리
REST와 같은 방식으로
이벤트를 외부에 제공
23. 이벤트 저장소 구현
❏ EventEntry
❏ 이벤트 저장소에 보관할 이벤트 데이터
❏ Id, Type, Content-Type, Payload, Timestamp
❏ EventStore
❏ 이벤트를 저장하고 조회하는 인터페이스
❏ JdbcEventStore
❏ JDBC를 이용한 EventStore구현 클래스
❏ EventApi
❏ REST API를 이용해서 이벤트 목록을 제공하는 컨트롤러
24. 이벤트 저장을 위한 이벤트 핸들러 구현
❏ 발생한 이벤트를 이벤트 저장소에 추가하는 로컬 이벤트 핸들러
25. REST API 구현
❏ Offset과 limit의 웹 요청 파라미터를 이용해서 EventStore#get을 실행하고 그
결과를 JSON으로 리턴
❏ API를 사용하는 클라이언트 동작
27. 포워더 구현
❏ API 방식에서 클라이언트의 구현과 유사
❏ 일정 주기로 EventStore로부터 이벤트를 읽어와 이벤트 핸들러에 전달
❏ 마지막으로 전달한 이벤트의 offset을 기억 해 두었다가 다음 조회 시점에
마지막으로 처리한 offset부터 이벤트를 조회하여 처리
28. 이벤트 적용 시 추가 고려사항
❏ 이벤트 소스(이벤트 발생주체)를 EventEntry에 추가할지 여부
❏ 특정 주체가 발생한 이벤트만 조회하는 기능을 구현할 수 있게됨
❏ 포워더에서 전송 실패를 얼마나 허용할 것이냐
❏ 이벤트 손실
❏ 로컬 핸들러를 이용한 비동기 구현에서는 이벤트 처리 실패 시 이벤트 유실
❏ 이벤트 순서 보장
❏ 이벤트 재처리
❏ 이벤트 처리를 멱등으로 처리- 중복 발생이나 중복처리에 대한 부담을 줄여줌