이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • 어떤 AI 기능은 동기 API로 두고 어떤 기능은 worker로 분리해야 하는가?
  • 비동기 job 처리에서 idempotency와 상태 관리가 왜 중요한가?
  • API 서버와 worker 사이 계약은 어떻게 잡아야 하는가?

개요

AI 작업은 처리 시간이 예측하기 어렵다. 짧은 분류는 동기 API로 충분하지만, 긴 문서 처리와 RAG 색인, agent workflow는 비동기 worker로 분리해야 API 서버를 보호할 수 있다.

동기 API 기준

동기 처리에 적합한 경우:

  • 짧은 입력
  • 짧은 출력
  • 3초에서 8초 안에 끝남
  • 실패 시 바로 재시도 가능
  • side effect 없음

예: 짧은 문의 분류, 간단한 문장 교정, 짧은 요약.

비동기 Worker 기준

worker에 적합한 경우:

  • 긴 문서
  • batch embedding
  • eval
  • RAG indexing
  • agent workflow
  • 파일 처리
  • 여러 tool 호출

이 경우 API는 job id를 반환하고 상태 조회를 제공한다.

코드로 이해하기

job 상태를 명확히 둔다.

public enum AiJobStatus {
    QUEUED,
    RUNNING,
    COMPLETED,
    FAILED,
    CANCELLED
}
 
public record AiJobMessage(
        String jobId,
        String tenantId,
        String userId,
        String traceId,
        String promptVersion,
        String idempotencyKey
) {
}

상태 전이가 있어야 retry와 중복 실행을 관리할 수 있다.

Worker 안정성

worker는 다음을 가져야 한다.

  • concurrency limit
  • idempotency key
  • DLQ
  • retry policy
  • job timeout
  • cancellation
  • result storage
  • trace propagation

queue 메시지는 중복 전달될 수 있다고 가정한다.

장애 상황과 대응

증상:

  • API timeout 증가
  • queue depth 증가
  • 같은 job 두 번 실행
  • DLQ 증가
  • worker가 provider rate limit을 초과

대응:

  • worker concurrency 조정
  • backpressure 적용
  • idempotency 확인
  • batch와 online queue 분리
  • DLQ 재처리 runbook 작성

인프라 협업 포인트

인프라팀과는 queue, worker autoscaling, rate limit, DLQ, job retention, streaming timeout을 합의한다.

개인 프로젝트 최소 기준

  • 긴 작업은 background job으로 뺀다.
  • job status를 DB에 저장한다.
  • 실패 이유를 남긴다.
  • worker 재시작 후에도 재처리 가능하게 한다.

기업 운영 수준 기준

  • queue depth와 job age 알림을 둔다.
  • worker pool을 workload별로 분리한다.
  • DLQ와 재처리 절차를 둔다.
  • tenant별 concurrency 제한을 둔다.

실전 팁

  • provider retry와 queue retry가 겹치지 않게 한다.
  • job payload에는 원문보다 resource id를 넣는다.
  • 사용자가 취소한 job은 worker가 확인할 수 있게 한다.
  • 결과 저장은 idempotent하게 만든다.

위험 신호!

  • 긴 AI 작업이 동기 Controller에서 실행된다.
  • job 상태가 없다.
  • queue 중복 전달을 고려하지 않는다.
  • DLQ가 있지만 모니터링하지 않는다.

확인 질문

확인 질문

  • queue worker가 idempotency를 가져야 하는 이유는 무엇인가?
    • 메시지가 중복 전달되거나 retry될 수 있기 때문이다.
  • AI 작업을 비동기로 분리하는 가장 큰 이유는 무엇인가?
    • API 서버 리소스와 사용자 요청 흐름을 긴 작업에서 보호하기 위해서다.

참고 문서