Skip to content

feat/008-error-fix #87

Description

@scv74502

목표

현재 구조에서 요구사항 대비 미비한 장애 처리, 복구, 동시성 방어를 보완하여 외부 API 연동 작업의 정합성과 복원력을 강화한다.

작업 항목

1. 외부 호출 복원력 예외 처리 보강

  • 완료

문제점/미비점

Resilience4j의 CircuitBreaker, RateLimiter, Bulkhead 및 네트워크/타임아웃 예외가 작업 재시도 정책으로 일관되게 연결되지 않는다.

구현 방법

  • Resilience4j 예외와 WebClient 네트워크 예외를 MockWorkerException으로 매핑한다.
  • 재시도 가능한 예외는 RecoveryAction.RETRY로 분류한다.
  • Retry-After 값이 있으면 실제 재시도 지연에 반영한다.

선택한 방법과 이유

외부 호출 실패를 오케스트레이터의 기존 재시도/상태 전이 흐름으로 흡수하는 방식이 가장 단순하며, DB 상태 기반 재처리 모델과도 일관된다.

2. API Key 401 재발급 로직 보강

  • 완료

문제점/미비점

401 응답을 받아도 기존 API Key가 메모리에 남아 있으면 재발급이 건너뛰어질 수 있다.

구현 방법

  • 401 발생 시 현재 사용한 Key를 기준으로 조건부 강제 재발급을 수행한다.
  • 동시 401 상황에서는 Mutex로 하나의 코루틴만 재발급하고 나머지는 갱신된 Key를 재사용한다.

선택한 방법과 이유

기존 Mutex 기반 동시성 제어를 유지하면서 만료된 Key만 교체할 수 있어, 불필요한 구조 변경 없이 문제를 해결할 수 있다.

3. PROCESSING 작업 복구 흐름 보강

  • 완료

문제점/미비점

서버 재시작 후 외부 작업이 아직 PROCESSING인 경우 기존 jobId 폴링을 재개하지 못하고 오케스트레이터에서 스킵될 수 있다.

구현 방법

  • PROCESSING 작업의 기존 externalJobId로 폴링을 재개하는 진입점을 추가한다.
  • 복구 서비스는 외부 상태가 PROCESSING이면 새 제출이 아니라 폴링 재개를 호출한다.

선택한 방법과 이유

이미 외부 서비스에 접수된 작업을 다시 제출하지 않고 기존 jobId를 추적하는 것이 중복 처리 비용을 줄이고 복구 의미에 가장 부합한다.

4. Task 상태 갱신 낙관적 잠금 보강

  • 완료

문제점/미비점

도메인 객체의 오래된 상태가 최신 DB 상태를 덮어쓸 수 있어 @Version 기반 충돌 감지 효과가 약하다.

구현 방법

  • 업데이트 시 도메인 version과 DB version을 비교한다.
  • 버전 불일치 시 stale update로 처리하고 최신 상태를 기준으로 후속 로직을 결정한다.

선택한 방법과 이유

JPA @Version을 유지하면서 애플리케이션 레벨에서도 의도를 명확히 검증할 수 있어, 현재 구조를 크게 바꾸지 않고 정합성을 높일 수 있다.

5. imageUrl 중복 요청 동시성 방어 보강

  • 완료

문제점/미비점

동일 imageUrl이 다른 멱등키로 동시에 들어오면 사전 조회를 모두 통과해 중복 작업이 생성될 수 있다.

구현 방법

  • imageUrl hash 기준 짧은 임계구역을 둔다.
  • MySQL 환경에서 동시 요청 중 하나만 생성되고 나머지는 기존 정책대로 409 처리되도록 한다.

선택한 방법과 이유

현재 시스템이 MySQL/Testcontainers 기반이므로 DB 기반 직렬화가 수평 확장 가능성과 구현 복잡도 사이에서 가장 현실적인 선택이다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions