주문 서비스 핵심 로직 설계 및 트래픽 대응 구조 - Genie-Uss/genieus GitHub Wiki

🧩 문제 상황 (Problem)

이커머스 도메인에서 주문 생성 흐름은 다음과 같은 복합적인 트랜잭션 처리 및 연동 문제에 직면했습니다:

  • 재고, 쿠폰, 결제 등 여러 서비스와의 연동이 필요하지만, 모두 동기 처리할 경우 시스템 병목 위험
  • 재고/쿠폰 연동 실패 시, 일괄 롤백이 필요한데, Kafka 기반 비동기 구조에서는 예외 전파가 어렵고 상태 복구가 복잡
  • 고트래픽 상황에서는 주문 요청이 몰려들어 DB 커넥션/락/서버 리소스 소모가 급증함
  • 주문 만료 처리도 실시간으로 처리하면 리소스 낭비가 심하고, 일관성 유지가 어려움

🎯 선택한 해결 방안 (Decision)

동기/비동기 흐름을 명확히 분리하고, 트래픽 분산과 장애 복구에 강한 구조를 적용했습니다:

  • 즉시 확인이 필요한 흐름은 동기 처리: 주문 생성 시 최저가 검증, 재고 예약FeignClient 기반 동기 호출
  • 후속 처리가 필요한 흐름은 비동기 처리: 주문 취소 시 재고 복구는 Kafka 이벤트 발행으로 지연 처리
  • 장애 복원력 확보를 위해 Resilience4j 적용: 서킷브레이커 + 재시도 설정을 통해 연동 서비스 장애 시 빠른 격리 가능
  • 주문 만료는 Redis 기반 Delay Queue 사용: ZSet + TTL 방식으로 주문 유효기간 관리 → 스케줄러가 일괄 만료 처리

🧩 주문 생성 흐름 시퀀스 다이어그램 (Mermaid)

sequenceDiagram
    participant Client
    participant OrderService
    participant PromotionService
    participant ProductService
    participant Redis
    participant Kafka

    Client->>OrderService: 주문 생성 요청
    OrderService->>PromotionService: 최저가 검증 (동기)
    PromotionService-->>OrderService: 검증 성공/실패
    OrderService->>ProductService: 재고 예약 (동기)
    ProductService-->>OrderService: 예약 성공/실패

    alt 성공 시
        OrderService->>OrderService: 주문 저장
        OrderService->>Redis: 만료 시각 등록 (ZSet)
        OrderService->>Kafka: 주문 생성 이벤트 발행
    else 실패 시
        OrderService-->>Client: 실패 응답
        OrderService->>Kafka: 주문 생성 실패 이벤트 발행
    end

    OrderService-->>Client: 주문 생성 결과 반환


적용 효과 (Outcome)

  • 동기/비동기 흐름의 분리로 핵심 로직의 트랜잭션 안정성 확보
  • Redis 기반 만료 구조 덕분에 성능 저하 없이 대량 주문 처리 가능
  • Resilience4j 도입을 통해 외부 장애에 대한 방어선 확보
  • Kafka 기반 이벤트 발행으로 쿠폰/재고 복구 흐름이 느슨하게 결합되어 확장성 강화
  • 전체 주문 요청 성공률 및 평균 응답시간이 트래픽 피크 시에도 안정적으로 유지됨

🔭 향후 개선 방향 (Next Steps)

  • 🔄 만료 처리 Poller 구조 개선: @Scheduled 기반에서 Kafka Delay Topic 구조로 전환 가능성 검토
  • ☁️ 트랜잭션 아웃박스 패턴 도입 검토: 주문 저장과 이벤트 발행을 완전한 원자성으로 처리
  • 🔎 관측성 향상: 주문 흐름에 대한 로그/메트릭 강화, k6 + Prometheus 기반 SLA 측정 체계 구축

💬 요약

“프로모션/상품 연동은 동기 호출로 즉시 보장하고, 복구·만료는 Kafka 이벤트와 Redis Delay Queue 기반으로 비동기 처리함으로써, 트래픽 상황에서도 안정적이고 유연한 주문 처리를 가능하게 했습니다.”