Eternity's Chit-Chat

aeternum.egloos.com



진화적인 설계-3.ACCOUNTING 패턴 4부 Evolutionary Design

EVENT SOURCING

EVENT SOURCING 패턴은 DOMAIN EVENT 패턴에 그 기반을 두고 있다.
EVENT SOURCING 패턴의 기본 아이디어는 애플리케이션 상태에 대한 모든 변경을 DOMAIN EVENT의 흐름으로 표현하고 애플리케이션의 상태를 변경시킨 순서에 맞추어 DOMAIN EVENT를 저장하는 것이다. 이를 통해 애플리케이션의 현재 상태뿐만 아니라 그 상태에 이르기까지의 기나긴 과정을 추적할 수 있다. EVENT SOURCING 패턴의 가장 큰 장점은 시스템의 상태 변경과 관련된 모든 이력을 보관하고 과거의 상태를 복구할 수 있다는 점이다.

EVENT SOURCING 패턴의 적용 여부에 따라 애플리케이션이 답변할 수 있는 질문의 유형이 결정된다. EVENT SOURCING 패턴을 적용하지 않은 애플리케이션에게는 오직 현재의 상태에 대해서만 질문할 수 있다. 애플리케이션이 과거의 상태에 대해서도 답하기를 원한다면 TEMPORAL 패턴과 같은 별도의 장치를 통해 기억력의 한계를 보완해 주어야 한다. 반면에 EVENT SOURCING 패턴을 적용한 애플리케이션에 대해서는 현재의 상태뿐만 아니라 과거의 상태와 상태의 변경 과정에 대해서도 질문이 가능하다. TEMPORAL 패턴과 같은 부가적인 장치의 도움이 없어도 DOMAIN EVENT를 저장하는 것만으로 시간을 거슬러 올라가는 능력을 부여 받을 수 있게 된다.

EVENT SOURCING 패턴의 적용 여부에 따라 애플리케이션의 아키텍처 역시 커다란 영향을 받게 된다. EVENT SOURCING 패턴을 적용하지 않는 계좌 관리 시스템을 생각해 보자. 이 시스템은 계좌의 최종 잔액만을 저장하고 상태 변경을 추적할 수 있는 별도의 정보는 저장하지 않을 것이다. 이 경우 입금과 출금 기능을 제공하는 애플리케이션의 전형적인 구조는 <그림 7>과 같다.

<그림 7> 최종 잔액만을 관리하는 계좌 관리 애플리케이션의 구조

계좌에 일정 금액을 입금하기 위해 deposit() 메소드가 호출되면 Account Service는 대상 Account의 balance 속성을 amount만큼 증가시킨다. 이 애플리케이션을 이용해 최종 잔액을 조회할 수는 있지만 TEMPORAL 패턴을 이용한 부가적인 장치를 사용하지 않는 한 deposit() 메소드 호출 이전의 잔액이나 변경 이력을 조회하는 것은 불가능하다.

EVENT SOURCING 패턴은 전형적인 애플리케이션에 DOMAIN EVENT를 생성하는 한 단계를 추가한다.

<그림 8> 모든 상태 변경을 DOMAIN EVENT로 표현

계좌에 일정 금액을 입금하기 위해 deposit() 메소드가 호출되면 Account Service는 계좌의 상태 변경을 처리할 DOMAIN EVENT인 Deposit Event를 생성하고 process() 메소드를 호출한다. Deposit Event는 잔액을 변경시킬 Account를 찾은 후 Account의 balance를 amount만큼 증가시켜 애플리케이션의 상태를 변경시킨다. 모든 처리가 완료된 후에는 Account의 balance뿐만 아니라 Deposit Event 역시 시스템에 저장된다.

<그림 8>은 동기 처리(synchronous processing) 방식의 EVENT SOURCING 패턴을 설명하고 있지만 <그림 2>에서 설명한 기본 아키텍처를 기반으로 비동기 처리(asynchronous processing) 방식으로 확장되고 변형될 수 있다. 예를 들어 Account Service는 직접 Deposit Event의 process() 메소드를 호출하지 않고 영속성 저장소인 이벤트 로그(Event Log)에 해당 Deposit Event를 저장하는 역할만 수행할 수도 있다. 이 경우 적절한 주기로 이벤트 프로세서(Event Processor)가 영속성 저장소에 저장된 Deposit Event를 읽어 process() 메소드를 호출함으로써 계좌의 잔액을 변경시킬 것이다.

<그림 9> 이벤트 로그(Event Log)를 이용한 비동기 처리 방식의 EVENT SOURCING

EVENT SOURCING 패턴은 애플리케이션의 모든 상태 변경이 오직 DOMAIN EVENT를 통해서만 이루어지도록 한정함으로써 다음과 같은 부가적인 장치를 애플리케이션에 제공할 수 있다.

  • 상태의 재구축 - 애플리케이션의 현재 상태를 완전히 폐기하고 이벤트 로그에 저장된 DOMAIN EVENT를 이용해서 애플리케이션의 상태를 완전히 재구축할 수 있다. 계좌 예제의 경우 계좌의 잔액을 0으로 초기화한 후 계좌 개설일인 2010년 8월 1일 이후에 통지된 모든 DOMAIN EVENT를 처리함으로써 최종 계좌 잔액을 재계산할 수 있다.
  • 과거 상태 조회 - 특정 시점의 애플리케이션 상태를 조회할 수 있다. 일반적으로 초기 상태에서 특정 시점까지 발생한 DOMAIN EVENT를 다시 처리함으로써 과거의 상태를 조회할 수 있다. 2010년 8월 18일의 계좌 잔액을 조회하고 싶다면 계좌의 잔액을 0으로 초기화한 후 2010년 8월 18일까지 발생한 모든 DOMAIN EVENT를 다시 처리함으로써 해당 일의 계좌 잔액을 구할 수 있다.
  • 오류 자동 복구 – 이미 처리된 DOMAIN EVENT에 오류가 존재할 경우 해당 DOMAIN EVENT 이후의 모든 상태 변경을 무효화한 후 새로운 DOMAIN EVENT를 이용해 애플리케이션 상태 오류를 수정할 수 있다. 앞에서 설명했던 RETROACTIVE EVENT를 이용한 계좌 오류의 수정 방법이 여기에 해당된다.

요약하면 EVENT SOURCING 패턴을 이용해서 애플리케이션의 상태와 관련된 두 가지 정보를 저장할 수 있다. 하나는 “애플리케이션 상태(Application State)”로 특정 속성의 현재 값을 의미한다. 계좌 관리 예제에서는 Account의 balance 속성이 애플리케이션 상태를 표현한다. 두 번째 정보는 애플리케이션 상태의 변경을 유발한 DOMAIN EVENT의 집합으로 이를 “이벤트 로그(Event Log)”라고 한다. 애플리케이션에 EVENT SOURCING 패턴을 적용하면 최종 상태의 애플리케이션 상태뿐만 아니라 이벤트 로그를 통해 어떤 시점의 애플리케이션 상태라도 조회가 가능하며 상태 변경의 원인과 과정을 추적하고 오류에 대한 수정을 자동화할 수 있다.