ddd start 10장

28
DDD start 10이벤트 아꿈사 송성곤

Upload: sung-gon-song

Post on 13-Jan-2017

103 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Ddd start 10장

DDD start

10장 이벤트아꿈사 송성곤

Page 2: Ddd start 10장

주요 내용❏ 이벤트의 용도와 장점❏ 핸들러 디스패치와 핸들러 구현 ❏ 비동기 이벤트 처리

Page 3: Ddd start 10장

시스템 간 강결합 문제 ❏ 쇼핑몰 구매 취소 시 환불 문제

❏ 주문 도메인에서 환불 기능을 실행

❏ 환불 도메인이 외부 시스템이라면❏ 환불처리 과정에서 예외발생으로 구매취소 트랜잭션도 롤백해야 하는가…❏ 외부 서비스 성능에 직접적인 영향을 받는다.

❏ 도메인 객체에 서비스를 전달하면❏ 주문로직과 결재로직이 섞이는 문제

Page 4: Ddd start 10장

시스템 간 강결합 문제를 해결하려면..❏ 이벤트를 사용하여 구매시스템과 결재 시스템간 강결합 문제를 해결❏ 이벤트를 사용하면 서로 다른 도메인이 섞이는 것을 방지할 수 있음

Page 5: Ddd start 10장

이벤트 관련 구성요소❏ 이벤트 생성 주체 ❏ 이벤트 디스패처(퍼블리셔)❏ 이벤트 핸들러

이벤트 생성 주체 이벤트 디스패쳐이벤트 퍼블리셔 이벤트 핸들러

event event

Page 6: Ddd start 10장

이벤트 구성 ❏ 이벤트 종류

❏ 클래스 이름으로 이벤트 종류 표현

❏ 이벤트 발생시간❏ 추가 데이터

❏ 주문번호, 신규 배송지 정보 등 이벤트와 관련된 정보

생성자

Page 7: Ddd start 10장

이벤트 용도 ❏ 트리거

❏ 시스템간의 데이터 동기화

Order EventDispatcher OrderCanceledEventHandler

OrderCanceled event

OrderCanceled event

RefundService

Page 8: Ddd start 10장

이벤트, 이벤트 핸들러, 디스패처 구현 ❏ 이벤트 클래스 (Event)❏ 이벤트 핸들러 (EventHandler)

❏ 이벤트 핸들러의 상위 타입으로 모든 핸들러는 이 인터페이스를 구현한다.

❏ 디스패처 (Events)❏ 이벤트 디스패처, 이벤트 발행, 이벤트 핸들러 등록, 이벤트를 핸들러에

등록하는 등의 기능을 제공

Page 9: Ddd start 10장

이벤트 클래스 ❏ 이벤트는 과거에 벌어진 상태 변화나 사건을 의미하므로 이벤트클래스의 이름을 결정할 때에는 과거 시제를 사용

❏ 접미사로 Event를 사용

❏ Event(s)❏ OrderAcceptedEvent❏ OrderCanceledEvent❏ OrderShippedEvent❏ CommentAddedEvent❏ ReviewQuarantinedEvent❏ ReviewUnquarantinedEvent

Page 10: Ddd start 10장

이벤트 핸들러

Page 11: Ddd start 10장

이벤트 디스패처

Page 12: Ddd start 10장

이벤트 디스패처

이벤트 발생

Page 13: Ddd start 10장

이벤트 디스패처

Page 14: Ddd start 10장

이벤트 디스패처

Page 15: Ddd start 10장

이벤트 디스패처

Page 16: Ddd start 10장

이벤트 처리 흐름

Page 17: Ddd start 10장

동기 이벤트 처리 문제 ❏ 시스템간 강결합은 해결했으나 외부시스템 성능 영향

환불처리가 느려진다면

Page 18: Ddd start 10장

비동기 이벤트 처리 ❏ ‘A하면 이어서 B하라’

❏ ‘A하면 최대 언제까지 B하라’로 바꿀수 있는 요구사항

❏ 비동기 이벤트 처리 방법

❏ 로컬 핸들러를 비동기로 실행❏ 메시지 큐를 사용한 비동기 구현❏ 이벤트 저장소와 이벤트 포워더 사용하기❏ 이벤트 저장소와 이벤트 API 사용하기

Page 19: Ddd start 10장

로컬 핸들러의 비동기 처리 ❏ 이벤트 핸들러를 별도 스레드로 이벤트 핸들러를 비동기로 실행

executor.submit(() -> handler.handle(event));

Page 20: Ddd start 10장

트랜잭션 범위

메시징 시스템을 이용한 비동기 구현

Order Events RabbitMQEvents.raise rabbitTemplate.convertAndSend()

MessageListener

EventHandler

onMessage()

handle()

트랜잭션 범위

Page 21: Ddd start 10장

이벤트 저장소와 이벤트 포워더 사용하기 ❏ 이벤트를 일단 DB에 저장❏ 포워더(별도 프로그램)를 이용 이벤트 핸들러에 이벤트 전달

도메인 이벤트 디스패처 로컬핸들러

포워더 이벤트핸들러

저장소

이벤트 저장

이벤트를 주기적으로 읽어와 전달 어디까지 전달했는지 추적

Page 22: Ddd start 10장

이벤트 저장소와 이벤트 API 사용하기 ❏ 이벤트를 일단 DB에 저장❏ 외부핸들러가 API서버를 통해 이벤트 목록을 가져오는 방식

도메인 이벤트 디스패처 로컬핸들러

API 이벤트핸들러

저장소

이벤트 저장

API를 통해 이벤트를 읽어와 처리

REST와 같은 방식으로 이벤트를 외부에 제공

Page 23: Ddd start 10장

이벤트 저장소 구현 ❏ EventEntry

❏ 이벤트 저장소에 보관할 이벤트 데이터 ❏ Id, Type, Content-Type, Payload, Timestamp

❏ EventStore❏ 이벤트를 저장하고 조회하는 인터페이스

❏ JdbcEventStore ❏ JDBC를 이용한 EventStore구현 클래스

❏ EventApi❏ REST API를 이용해서 이벤트 목록을 제공하는 컨트롤러

Page 24: Ddd start 10장

이벤트 저장을 위한 이벤트 핸들러 구현 ❏ 발생한 이벤트를 이벤트 저장소에 추가하는 로컬 이벤트 핸들러

Page 25: Ddd start 10장

REST API 구현 ❏ Offset과 limit의 웹 요청 파라미터를 이용해서 EventStore#get을 실행하고 그 결과를 JSON으로 리턴

❏ API를 사용하는 클라이언트 동작

Page 26: Ddd start 10장

REST API 구현

Page 27: Ddd start 10장

포워더 구현 ❏ API 방식에서 클라이언트의 구현과 유사 ❏ 일정 주기로 EventStore로부터 이벤트를 읽어와 이벤트 핸들러에 전달 ❏ 마지막으로 전달한 이벤트의 offset을 기억 해 두었다가 다음 조회 시점에 마지막으로 처리한 offset부터 이벤트를 조회하여 처리

Page 28: Ddd start 10장

이벤트 적용 시 추가 고려사항 ❏ 이벤트 소스(이벤트 발생주체)를 EventEntry에 추가할지 여부

❏ 특정 주체가 발생한 이벤트만 조회하는 기능을 구현할 수 있게됨

❏ 포워더에서 전송 실패를 얼마나 허용할 것이냐❏ 이벤트 손실

❏ 로컬 핸들러를 이용한 비동기 구현에서는 이벤트 처리 실패 시 이벤트 유실

❏ 이벤트 순서 보장❏ 이벤트 재처리

❏ 이벤트 처리를 멱등으로 처리- 중복 발생이나 중복처리에 대한 부담을 줄여줌