분산 아키텍처는 통신, 일관성, 조정이라는 세 가지 요소가 관여한다.

 

여기서는 그 중 '조정' 에 대해서 살펴본다.

 

'조정' 이라는 것은 워크플로우를 관리하는 스타일에 따라서 '오케스트레이션 (Orchestration)' 과 '코레오그레피(choreography)' 로 나뉜다.

 

하나씩 살펴보자.


1. 오케스트레이션 (Orchestration)

오케스트레이션 방식은 오케스트레이터 또는 중재자 (Mediator) 를 따로 두고 이를 중심으로 워크플로우를 처리해 나가는 것을 말한다.

 

작업의 워크플로우는 작업을 성공시키는 '정상 경로' 만 있는 것이 아니다.

 

작업을 실패했을 때 실패에 대해서 처리하는 '실패 경로' 와 작업의 실패에 대해서 보상 처리하는 '보상 경로' 가 있다.

 

오케스트레이션 방식의 스타일은 이런 워크플로우 관리가 쉽기 때문에 사용한다.

 

예시로 살펴보자.

 

다음은 주문을 처리하는 아키텍처에서 정상적인 작업의 성공을 다루는 워크플로우이다.

  • 작업의 처리과정은 다음과 같다:
    • Step 1) '오케스트레이터'에서 주문 요청을 받고, 이를 '주문 서비스'로 전달한다. 그리고 주문이 만들어지면 다시 '오케스트레이터'로 응답한다. 그러면 '오케스트레이터' 는 상태를 업데이트 한다.
    • Step 2) 주문 생성 작업이 끝나면 '오케스트레이터'는 '결제 서비스'에 요청해서 결제를 한다. 결제가 성공하면 다시 '오케스트레이터'로 응답한다. 그러면 '오케스트레이터' 는 상태를 업데이트 한다.
    • Step 3) '오케스트레이터'는 '주문 이행 서비스' 에 재고 감소와 배송을 요청한다. 주문 이행이 성공되면 다시 '오케스트레이터'로 응답한다. 그러면 '오케스트레이터' 는 상태를 업데이트 한다.
    • Step 4) '오케스트레이터' 는 '이메일 서비스' 를 통해서 고객에게 주문이 성공되었음을 전달한다. 그리고 상태를 업데이트한다.
  • Step 3 의 과정은 비동기로 요청할 수 있다. 이 작업은 당장 해야하는 일이 아니라서, 즉 Timing Depedency 가 없기 때문에 비동기로 요청해도 괜찮다.
  • 이 시스템 구조는 동기식 통신 + 오케스트레이션 + 최종적 일관성을 만족시키는 아키텍처다. 착각하는게 있는데 최종적 일관성은 이벤트 기반의 비동기 방식으로만 할 수 있는게 아니다. 동기식 통신 방식으로도 이뤄질 수 있다. 최종적 일관성은 한번에 모든 데이터가 Atomic 하게 업데이트 되는 것을 말하는게 아니라 최종적으로 시간이 지나면 무결성을 만족시키는 상태가 된다는게 최종적 일관성이다.

 

 

 

다음은 결제가 실패한 경우를 처리하는 워크플로우다:

  • 이 경우에 오케스트레이터는 결제 실패를 수신하고, 이메일 서비스로 고객에게 주문이 실패했음을 알려준다.

 

 

 

다음은 결제는 성공했지만, 재고가 없어서 주문이 실패하는 워크플로우다:

  • 이 경우에 오케스트레이터는 백오더 (= 재고 없음) 상태임을 수신하고, 주문 서비스에 주문 실패 처리를 요청하고, 결제 서비스에는 환불 요청을 처리하며, 이메일 서비스에 주문이 실패되었음을 알려준다.
  • (이 서비스와 달리 대부분의 온라인 쇼핑몰 서비스는 결제 전에 재고 확인을 먼저 수행할 것임.)

 

1.1 오케스트레이션 정리

오케스트레이션 방식은 워크플로우 관리가 쉽기 때문에 사용한다고 했다.

 

이를 통해 오케스트레이션은 실패한 작업을 파악하고 이를 성공시키거나, 되돌리는 등의 작업을 하기 쉽다. (Reslience 가 있다!)

 

이는 오케스트레이터가 작업의 '상태 정보' 를 관리하며, 각 상태에 따라서 그리고 작업의 처리 성공과 실패에 따라서 처리해야할 로직을 관리해주기 때문이다.

 

그럼 오케스트레이션 방식의 단점은 무엇일까?

 

기존 서비스에 오케스트레이터가 추가되기 떄문에 발생하는 단점이다. 다음과 같다:

  • 확장성 문제 (Scalability):
    • 오케스트레이션도 같이 확장해야하며, 여기서 병목이 생기면 안된다.
  • Fault Tolerance:
    • 오케스트레이터가 Single Point of Failure 가 될 수 있다.
  • Latency:
    • 오케스트레이션이라는 추가적인 컴포넌트를 두고 통신을 하니까 Network Hop 수가 늘어나서 Latency 가 늘어난다.
  • Coupling:
    • 오케스트레이션은 여러 서비스들과 협력하면서 결합도가 높아진다.

2. 코레오그레피 (choreography)

코레오그래피 방식은 워크플로우를 관리할 때 의도적으로 중재자를 만들지 않고 각 서비스가 필요한 서비스들을 호출하는 식으로 워크플로우를 관리한다.

 

그래서 다음과 같이 주문 처리 시스템의 정상 경로에선 통신이 비교적 간단해진다. 

 

 

그러나 코레오그래피 방식은 워크플로우가 정상 경로가 아닐 때, 실패 처리의 경로나 보상 처리의 경로가 발생할 때 오케스트레이션보다 복잡한 워크플로우를 가진다.

 

예시를 살펴보자.

 

다음 예시는 결제 서비스에서 주문의 결제가 실패한 상황이 발생한 경우다:

  • 이 경우를 처리하기 위해서 결제 서비스는 주문 서비스에 실패했음을 알려주고, 이메일 서비스를 호출해서 고객에게 주문이 실패했음을 전달한다.

 

다음 예시는 주문 이행 서비스에서 재고가 부족한 상황이 발생한 경우다:

  • 이 경우를 처리하기 위해서 주문 이행 서비스는 결제 서비스에 환불해야함을 알려주고, 주문 서비스에 재고가 없음을 알려주고, 이메일 서비스를 호출해서 고객에게 주문이 실패했음을 알려준다.

 

즉 코레오그래피 방식은 각 서비스에서 자신의 작업 처리가 실패되었을 때 실패 처리에 대한 작업 경로와, 보상 처리에 대한 작업 경로에 대한 지식을 알고 있어야 하기 때문에 워크플로우 관리가 어려운 것이다.

 

오케스트레이션은 이 모든 관리를 중재자에서만 하면 되니까.

 

2.1 워크플로우 상태 관리

코레오그래피에서 워크플로우의 상태 관리는 어떻게 될까?

 

상태 관리 패턴은 다음과 같다:

  • 프론트 컨트롤러 패턴
  • 무상태 패턴
  • 스탬프 커플링 패턴

 

프론트 컨트롤러 패턴:

  • 상태 관리를 요청이 처음 도착하는 서비스에서 관리하는 것이다.
  • 상태 관리에 대한 명확한 이해를 준다는 장점이 있으나, 상태 관리를 하기 위해서 계속 첫 서비스에 요청을 보내는 통신 오버헤드가 생긴다는 문제점이 있다.
  • 이로인해 확장성에도 문제가 될 수 있다. 

 

 

무상태 패턴:

  • 상태를 관리하지 않는 방식이다.
  • 그러므로 무상태 패턴은 작업을 처리하기 위해서 상태를 먼저 파악해보기 위해서 연계된 서비스를 쿼리해보고 상태를 파악한 후 작업을 진행한다.
  • 이 방식은 상태를 유지하지 않기 때문에 유연하다는 장점이 있지만 상태를 알기 위한 작업에는 리소스가 많이든다.

 

스탬프 커플링 패턴:

  • 상태를 관리하는 서비스는 따로 존재하지 않으나, 메시지를 전달할 때 워크플로우에 현재 어떤 상태인지를 기록해서 던져준다.
  • 따라서 각 서비스는 해당 메시지의 상태에 따라서 처리하기만 하면 되고, 메시지에 현재 어느 상태까지 왔는지 전달해주기만 하면 된다.
  • 이 부분은 그래도 메시지에 상태가 포함되어 있어서 상태에 따라서 행동을 하면 되니까 명확하게 작업을 수행할 수 있다.
  • 프론트 컨트롤러 패턴에 비해서 확장성은 있으나, 추가적인 메시지 전달을 해야하며 서비스간의 결합이 강하게 되는 점에서 문제가 있다. 
  • 이 시스템에서 현재 처리중인 서비스의 상태를 파악하려면 연계된 서비스를 호출해봐야한다.
  • 이 시스템에서 일관성을 맞추려면 워크플로우의 끝에 있는 서비스에서 연계된 서비스를 모두 호출해서 상태를 파악하고 일관성을 맞추기 위한 메시지를 던져줘야한다. 

 

2.2 정리

코레오그래피 방식은 오케스트레이션이 가지지 못한 단점을 장점으로 취한다. (e.g Scalability, Fault Tolerance, Latency)

그러나 오케스트레이션이 가진 장점을 단점으로서 가진다. (e.g 워크플로우 관리)

+ Recent posts