개요

사가는 마이크로서비스 아키텍처에서 분산 트랜잭션 없이 데이터 일관성을 유지하는 메커니즘입니다. 여러 서비스의 데이터를 업데이트하는 시스템 커맨드마다 사가를 하나씩 정의합니다. 사가는 일련의 로컬 트랜잭션입니다. 각 로컬 트랜잭션은 앞서 언급한 ACID 트랜잭션 프레임워크/라이브러리를 이용하여 서비스별 데이터를 업데이트합니다.

(중략)

사가와 ACID 트랜잭션은 두 가지 중요한 차이점이 있습니다. 첫째, ACID 트랜잭션에 있는 격리성(I)이 사가에는 없습니다. 둘째, 사가는 로컬 트랜잭션마다 변경분을 커밋하므로 보상 트랜잭션을 걸어 롤백해야 합니다. 1

예제: 주문 생성 사가

정상적인 주문 과정이 완료될 때까지 6개의 서비스의 상태를 순차적으로 변경시킨다고 하자.

시퀀스 서비스 작업
0   회원이 A 상품을 2개 장바구니에 넣고 주문.
1 주문 주문을 주문 대기 상태로 생성.
2 회원 주문 가능한 회원이라는 사실을 확인.
3 재고 재고 수량 확인 후 주문 상품에 대해 재고 차감 대기 상태 생성.
4 결제 신용 카드 사용을 승인.
5 재고 주문 상품의 재고를 2개 감소시키고, 재고 차감 완료 상태로 업데이트.
6 주문 주문을 주문 완료 상태로 업데이트.

각 서비스는 로컬 트랜잭션이 완료되면 메시지를 발행하여 다음 사가 단계를 트리거한다.

만약 중간에 에러가 발생하면 보상 트랜잭션을 사용해 롤백을 구현한다.

시퀀스 서비스 작업  
0   회원이 A 상품을 2개 장바구니에 넣고 주문.  
1 주문 주문을 주문 대기 상태로 생성.  
2 회원 주문 가능한 회원이라는 사실을 확인.  
3 재고 재고 수량 확인 후 주문 상품에 대해 재고 차감 대기 상태 생성.  
4 결제 신용 카드 사용 실패. 실패!
5 재고 주문 상품의 재고를 2개 감소시키고, 재고 차감 취소 상태로 업데이트. Undo
6 주문 주문을 주문 실패 상태로 업데이트. Undo

사가 편성 방법

사가 편성 로직은 두 가지가 있다.

  • 코레오그래피(choreography): 의사 결정과 순서화를 사가 참여자에게 맡깁니다. 사가 참여자는 주로 이벤트 교환 방식으로 통신합니다.
  • 오케스트레이션(orchestration): 사가 편성 로직을 사가 오케스트레이터에 중앙화합니다. 사가 오케스트레이터는 사가 참여자에게 커맨드 메시지를 보내 수행할 작업을 지시합니다. 2

코레오그래피 사가

간단한 사가라면 코레오그래피로도 충분하다.

  • 각 서비스는 이벤트를 구독하는 방식으로 작동한다. 다른 서비스에 대해 알지 못한다.
  • 여러 서비스에 구현 로직이 나뉘어 있어 사가 전체를 파악하기 어렵다.
  • 서비스 간 순환 의존성이 있다.
  • 사가 참여자는 자신에게 영향을 미치는 모든 이벤트를 구독해야 한다.

오케스트레이션 사가

복잡한 사가는 오케스트레이션이 적합한 경우가 많다.

오케스트레이션 사가에서는 사가 참여자가 할 일을 알려 주는 오케스트레이터 클래스(orchestrator class)를 정의합니다. 사가 오케스트레이터는 커맨드/비동기 응답 상호 작용을 하며 참여자와 통신합니다. 즉, 사가 단계를 실행하기 위해 해당 참여자가 무슨 일을 해야 하는지 커맨드 메시지에 적어 보냅니다. 사가 참여자가 작업을 마치고 응답 메시지를 오케스트레이터에 주면, 오케스트레이터는 응답 메시지를 처리한 후 다음 사가 단계를 어느 참여자가 수행할지 결정합니다. 3

오케스트레이션 사가의 장점은 다음과 같다.

  • 의존 관계가 단순하다.
    • 오케스트레이터만 참여자를 호출하기 때문이다.
    • 참여자는 오케스트레이터를 호출하지 않는다.
  • 각 서비스는 오케스트레이터 호출 API만 구현하면 된다.

참고문헌

  • [RIC] 마이크로서비스 패턴 / 크리스 리처드슨 저/이일웅 역 / 길벗 / 초판발행 2020년 01월 30일

주석

  1. [RIC] 4.1.3장. 

  2. [RIC] 4.2장. 

  3. [RIC] 4.2.2장.