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 방식의 장점
- 확장성:
- 상태를 직접 관리하지 않으므로, 여러 인스턴스를 쉽게 확장할 수 있습니다.
- 독립성:
- 각 서비스가 독립적으로 동작하므로, 특정 서비스 장애가 다른 서비스에 영향을 주지 않습니다.
- 이벤트 기반 통합:
- 상태 관리 대신 이벤트를 활용하여 서비스 간 결합도를 낮췄습니다.
코레오그래피 기반 SAGA 패턴 적용
1. 주문/결제와 상품 재고 변경 흐름
- 주문 및 결제 이벤트 발행
- 고객이 주문 및 결제를 완료하면, 주문 서비스에서 주문 생성 및 결제 완료 이벤트가 발행됩니다.
- 상품 재고 변경 처리
- 결제 완료 이벤트를 구독한 상품 서비스가 재고 감소 작업을 수행합니다.
- 재고 변경 실패 시 보상 트랜잭션
- 상품 재고 변경 작업이 실패할 경우, 보상 트랜잭션으로 주문 및 결제 취소 이벤트를 발행합니다.
- 이를 통해 주문 상태를 "CANCELED"로 변경하고, 결제를 취소하여 데이터 일관성을 유지합니다.
2. 배송 이벤트 생성 흐름
- 배송 대기 상태 조회
- 매일 오후 4시에 주문 서비스에서 배송 대기 상태(PENDING)인 주문을 조회합니다.
- 배송 이벤트 발행
- 배송 대기 상태의 주문에 대해 배송 이벤트를 발행합니다.
- 배송 서비스는 이를 구독하여 배송 프로세스를 시작합니다.
3. 고객 주문 취소 처리 흐름
- 고객이 주문 취소 요청
- 고객이 주문을 취소하면, 주문 서비스에서 주문 상태를 'CANCELED'로 변경하는 이벤트를 발행합니다.
- 상품 재고 복구
- 상품 서비스는 주문 취소 이벤트를 구독하여, 해당 상품의 재고를 복구합니다.
- 결제 취소 처리
- 결제 서비스는 주문 취소 이벤트를 구독하여, 결제 취소 작업을 수행합니다.
- 이를 통해 고객의 주문 취소 요청이 모든 서비스에서 일관되게 반영됩니다.
코레오그래피 기반 SAGA 패턴의 특징
- 분산 트랜잭션 관리
각 서비스는 독립적으로 동작하며, 이벤트를 통해 필요한 작업을 연결합니다.
예: 주문 서비스 -> 상품 재고 서비스 - 보상 트랜잭션 적용
재고 변경 실패 시, 주문 및 결제를 취소하는 보상 트랜잭션으로 데이터 일관성을 유지합니다. - Stateless 설계
상태를 서비스 간 이벤트로 주고받아, 강한 결합 없이 분산 환경에서 안정적으로 동작합니다.
설계의 장점
- 유연성: 각 서비스가 독립적으로 동작하므로, 장애가 발생해도 다른 서비스에 영향을 최소화합니다.
- 확장성: 새로운 서비스를 추가하거나 기존 서비스를 수정할 때, 이벤트 기반으로 쉽게 확장 가능합니다.
- 일관성: 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 |