본문 바로가기

기술 블로그 (Tech Blog)/Project-coopang

Coopang 프로젝트: Stateless 구조와 코레오그래피 기반 SAGA 패턴 적용 사례Stateless 구조코레오그래피 기반 SAGA 패턴 적용 사례

Coopang 프로젝트에서는 Stateless 구조코레오그래피 기반 SAGA 패턴을 활용하여, 마이크로서비스 간의 데이터 일관성과 트랜잭션 관리를 효과적으로 구현했습니다. 이번 글에서는 프로젝트에서 적용한 설계 흐름과 주요 특징을 소개합니다.

 

https://github.com/dev-wonny/coopang/issues/52#issuecomment-2401670930

 

[시나리오] 수정사항 · Issue #52 · dev-wonny/coopang

 

github.com

Git Project에서 stateless 시나리오 과정을 자세히 볼 수 있습니다.


Stateless 구조

Stateless는 서버가 요청 간의 상태를 유지하지 않는 구조를 의미합니다.

각 요청은 독립적이어야 하며, 필요한 모든 정보를 클라이언트에서 전달받거나 외부 데이터 소스를 통해 확인해야 합니다.

중요한 점은 서버가 상태(예: 세션, 상태 값)를 기억하지 않아야 한다는 것입니다.

 

재고 확인, 주문, 결제, 결제 기록 생성, 재고 감소, 주문 상태 변경, 배송이 각각 독립적인 api로 전달됩니다.

  • 결제, 주문, 결제 기록 생성, 재고 확인, 주문 상태 변경, 배송은 각각 독립적인 API로 처리됩니다.
  • 서비스 간의 상태 정보는 이벤트 메시지를 통해 공유됩니다.

Stateless 방식에서의 동작

  • 결제 요청: 결제 서비스는 결제 정보를 받아 처리하고, 성공/실패 결과를 반환합니다.
  • 주문 생성: 주문 서비스는 주문 데이터를 생성하고 이벤트를 발행합니다.
  • 재고 확인 및 업데이트: 상품 서비스는 주문 이벤트를 구독하여 재고를 확인하고 감소합니다. 실패 시 이벤트를 발행합니다.
  • 주문 상태 변경: 주문 서비스는 재고 작업의 성공/실패 이벤트를 구독하여 주문 상태를 업데이트합니다.

Stateless 방식에서의 프로세스 흐름

다음은 Stateless 방식에서 API와 서비스 간의 흐름을 간단히 설명한 예입니다:

 

상품 상세 페이지에서 '주문하기' 버튼을 눌러 주문/결제 페이지로 이동합니다.
이 과정에서 재고 검증Redis를 활용하여 주문 페이지 접속 시 이루어집니다.
만약 유효한 재고 수량이 존재하면 주문/결제 페이지에 정상적으로 도달할 수 있습니다.

즉, 주문 페이지 요청 시 재고 상태를 실시간으로 확인하여 사용자의 주문 가능 여부를 결정합니다.

 

  • 결제 요청
    • 클라이언트가 결제 서비스에 요청을 전송 → 결제 성공/실패 결과 반환.

결제 실패 시

  • 실패하면 유저가 결제 실패인걸 알아차림
  • 주문 서버에 요청 안감

결제 성공 시

  • 결제 성공 후 프론트엔드에서 2개의 요청을 동시에 날림
    • 결제 히스토리 기록 요청
    • 주문 생성 요청
  • 2개의 요청의 성공/실패 여부 상관 없이 유저는 주문이 생성되었다는 페이지로 이동 시킴

 

 

  • 주문 생성
    • 클라이언트가 주문 서비스에 요청을 전송 → 주문 생성 및 초기 상태 설정.

 

  • READY로 주문 최초 생성함
  • 카프카로 상품 토픽에게 재고 감소 요청함
  • 재고 감소 실패 여부 기다리지 않음

 

  • 재고 확인 및 감소
    • 상품 서비스가 주문 이벤트를 구독하여 재고 확인 및 감소 → 성공/실패 이벤트 발행.

 

  • 카프카 상품 토픽 --> 상품서버에 재고 감소 처리
  • 상품id로 재고 테이블에서 재고 개수를 조회함
  • 재고 개수 - 요청 개수 > 0 이면
    - 재고 변경 업데이트
    - 재고 히스토리 insert With orderId
    - 카프카 주문 토픽에게 보냄, 재고 감소 성공했다고

 

  • 주문 상태 변경
    • 주문 서비스가 재고 감소 성공/실패 이벤트를 구독 → 주문 상태 업데이트.

 

  • 카프카 주문 토픽 -> 주문 서버 상태 변경
  • 주문 update, 상태(PENDING)
    • 재고 감소 & 결제 완료 후 라서 → 상태PENDING 변경

Stateless 방식의 장점

  1. 확장성:
    • 상태를 직접 관리하지 않으므로, 여러 인스턴스를 쉽게 확장할 수 있습니다.
  2. 독립성:
    • 각 서비스가 독립적으로 동작하므로, 특정 서비스 장애가 다른 서비스에 영향을 주지 않습니다.
  3. 이벤트 기반 통합:
    • 상태 관리 대신 이벤트를 활용하여 서비스 간 결합도를 낮췄습니다.

 


코레오그래피 기반 SAGA 패턴 적용

 

1. 주문/결제와 상품 재고 변경 흐름

  1. 주문 및 결제 이벤트 발행
    • 고객이 주문 및 결제를 완료하면, 주문 서비스에서 주문 생성  결제 완료 이벤트가 발행됩니다.
  2. 상품 재고 변경 처리
    • 결제 완료 이벤트를 구독한 상품 서비스가 재고 감소 작업을 수행합니다.
  3. 재고 변경 실패 시 보상 트랜잭션
    • 상품 재고 변경 작업이 실패할 경우, 보상 트랜잭션으로 주문 및 결제 취소 이벤트를 발행합니다.
    • 이를 통해 주문 상태를 "CANCELED"로 변경하고, 결제를 취소하여 데이터 일관성을 유지합니다.

2. 배송 이벤트 생성 흐름

  1. 배송 대기 상태 조회
    • 매일 오후 4시에 주문 서비스에서 배송 대기 상태(PENDING)인 주문을 조회합니다.
  2. 배송 이벤트 발행
    • 배송 대기 상태의 주문에 대해 배송 이벤트를 발행합니다.
    • 배송 서비스는 이를 구독하여 배송 프로세스를 시작합니다.

3. 고객 주문 취소 처리 흐름

  1. 고객이 주문 취소 요청
    • 고객이 주문을 취소하면, 주문 서비스에서 주문 상태를 'CANCELED'로 변경하는 이벤트를 발행합니다.
  2. 상품 재고 복구
    • 상품 서비스는 주문 취소 이벤트를 구독하여, 해당 상품의 재고를 복구합니다.
  3. 결제 취소 처리
    • 결제 서비스는 주문 취소 이벤트를 구독하여, 결제 취소 작업을 수행합니다.
    • 이를 통해 고객의 주문 취소 요청이 모든 서비스에서 일관되게 반영됩니다.

코레오그래피 기반 SAGA 패턴의 특징

  • 분산 트랜잭션 관리
    각 서비스는 독립적으로 동작하며, 이벤트를 통해 필요한 작업을 연결합니다.
    예: 주문 서비스 -> 상품 재고 서비스
  • 보상 트랜잭션 적용
    재고 변경 실패 시, 주문 및 결제를 취소하는 보상 트랜잭션으로 데이터 일관성을 유지합니다.
  • Stateless 설계
    상태를 서비스 간 이벤트로 주고받아, 강한 결합 없이 분산 환경에서 안정적으로 동작합니다.

설계의 장점

  1. 유연성: 각 서비스가 독립적으로 동작하므로, 장애가 발생해도 다른 서비스에 영향을 최소화합니다.
  2. 확장성: 새로운 서비스를 추가하거나 기존 서비스를 수정할 때, 이벤트 기반으로 쉽게 확장 가능합니다.
  3. 일관성: SAGA 패턴을 통해 분산 환경에서도 데이터의 일관성을 보장합니다.

'기술 블로그 (Tech Blog) > Project-coopang' 카테고리의 다른 글

repository 설계  (0) 2024.12.26
Coopang 프로젝트: 멀티 모듈 구조와 역할 정리  (0) 2024.11.19
local 통합 테스트  (0) 2024.10.25
슬랙으로 메세지 보내기  (0) 2024.10.23
mapper  (0) 2024.10.23