/////

Message Queue Consumer Acknowledgement Failure Modes: Visibility Timeouts, Redelivery Storms, Poison Messages, and Idempotent Handler Boundaries

메시지 큐 consumer acknowledgement 장애의 핵심은 “메시지를 언제 성공 처리로 확정할 것인가”와 “실패·지연·중복 전달을 어디까지 허용할 것인가”의 경계 설정이다. SQS 계열에서는 visibility timeout 동안 메시지가 다른 consumer에게 보이지 않지만, 처리 후 삭제하지 못하면 다시 visible 상태가 되어 재전달될 수 있다. RabbitMQ/AMQP 계열에서는 manual ack, nack, reject, requeue

/////

Summary#

메시지 큐 consumer acknowledgement 장애의 핵심은 “메시지를 언제 성공 처리로 확정할 것인가”와 “실패·지연·중복 전달을 어디까지 허용할 것인가”의 경계 설정이다. SQS 계열에서는 visibility timeout 동안 메시지가 다른 consumer에게 보이지 않지만, 처리 후 삭제하지 못하면 다시 visible 상태가 되어 재전달될 수 있다. RabbitMQ/AMQP 계열에서는 manual ack, nack, reject, requeue 동작이 메시지 삭제·재전달·dead-lettering 여부를 결정한다.

따라서 큐 consumer는 “정확히 한 번 처리”를 전제로 설계하면 안 된다. 안전한 기본값은 at-least-once delivery + idempotent handler + bounded retry + DLQ/dead-letter exchange + 관측 가능한 redelivery 지표이다. 특히 visibility timeout이 처리 시간보다 짧거나, nack/requeue를 무한 반복하거나, poison message를 격리하지 않으면 redelivery storm이 발생해 정상 메시지 처리까지 방해할 수 있다.

Key Points#

  • Acknowledgement는 business success boundary여야 한다
  • 메시지를 받았다는 사실만으로 ack/delete하면 consumer crash, downstream 실패, DB write 실패 시 메시지를 잃을 수 있다.
  • 일반적으로는 handler가 필요한 영속 상태 변경, 외부 호출 결과 기록, 중복 방지 기록 등을 완료한 뒤 ack/delete해야 한다.
  • 반대로 ack를 너무 늦게 하거나 처리 시간이 visibility timeout을 넘으면 동일 메시지가 다른 consumer에게 다시 전달될 수 있다.

  • SQS visibility timeout은 lock이 아니라 재전달 지연 장치다

  • SQS에서 메시지는 consumer에게 전달된 뒤 visibility timeout 동안 다른 consumer에게 보이지 않는다.
  • consumer가 처리 후 DeleteMessage를 하지 않으면 timeout 만료 후 메시지가 다시 visible해지고 재처리될 수 있다.
  • AWS 문서는 standard/FIFO 모두에서 visibility timeout이 중복 처리를 완전히 막는 보장이 아니며, at-least-once delivery 때문에 중복 전달 가능성을 고려해야 한다고 설명한다.
  • 처리 시간이 가변적인 작업은 heartbeat 방식으로 ChangeMessageVisibility를 호출해 timeout을 연장할 수 있다.
  • 너무 짧은 timeout은 동시 중복 처리와 retry storm을 유발하고, 너무 긴 timeout은 실패 복구를 지연시킨다.

  • Redelivery storm은 retry 정책 부재에서 발생한다

  • 예: downstream DB 장애, 잘못된 schema, 항상 exception을 발생시키는 메시지, timeout misconfiguration.
  • 모든 consumer가 같은 메시지를 받고 실패한 뒤 즉시 requeue하면, 큐 처리량이 poison message 재시도에 소모된다.
  • SQS에서는 visibility timeout 만료 후 같은 메시지가 반복 수신될 수 있고, RabbitMQ에서는 nack/reject with requeue가 반복되면 큐 앞쪽 근처로 재삽입되어 빠르게 재전달될 수 있다.
  • 완화책:

    • 최대 수신/전달 횟수 설정
    • exponential backoff 또는 delayed retry
    • DLQ/dead-letter exchange 사용
    • consumer concurrency 제한
    • redelivery count, receive count, in-flight count, DLQ depth 모니터링
    • 장애 원인이 transient인지 permanent인지 구분
  • Poison message는 정상 retry와 분리해야 한다

  • poison message는 재시도해도 계속 실패하는 메시지다. 예: schema 불일치, 필수 필드 누락, 더 이상 존재하지 않는 entity 참조, handler bug trigger.
  • SQS에서는 여러 번 처리 실패한 메시지를 DLQ로 이동시켜 main queue 순환을 막는 것이 일반적이다.
  • RabbitMQ quorum queue 문서는 delivery count가 delivery limit을 초과하면 메시지를 dead-letter 또는 discard할 수 있음을 설명한다.
  • DLQ는 단순 폐기장이 아니라 분석·수정·재주입(redrive)을 위한 격리 영역이어야 한다.
  • DLQ 메시지는 원본 payload, failure reason, consumer version, stack trace hash, receive count, first failure time, last failure time 등을 보존하는 것이 좋다.

  • RabbitMQ ack/nack/reject 차이를 설계에 반영해야 한다

  • basic.ack: consumer가 성공 처리했음을 broker에 알리고 메시지를 삭제 가능 상태로 만든다.
  • basic.reject: 단일 메시지를 reject하며 discard/dead-letter 또는 requeue할 수 있다.
  • basic.nack: RabbitMQ 확장으로, reject와 유사하지만 bulk negative ack를 지원한다.
  • RabbitMQ 문서는 consumer acknowledgement가 publisher confirm과 별개이며, manual acknowledgement가 데이터 안전성 측면에서 중요하다고 설명한다.
  • RabbitMQ 문서는 redelivery를 처리할 준비와 idempotent consumer 구현 필요성을 명시한다.
  • delivery tag는 channel scope이므로, 받은 channel이 아닌 다른 channel에서 ack하면 protocol exception이 발생할 수 있다.

  • Idempotent handler boundary를 명확히 해야 한다

  • 중복 전달은 실패 케이스가 아니라 정상 운영 조건으로 취급해야 한다.
  • idempotency boundary는 “이 메시지가 이미 business effect를 냈는가?”를 판단하는 지점이다.
  • 일반적인 패턴:
    • message id / event id 기반 processed-message table
    • business key + operation type에 unique constraint 적용
    • 상태 전이 조건부 update: WHERE state = expected
    • 외부 API 호출 전후 request idempotency key 사용
    • side effect 결과를 먼저 기록하고 ack는 마지막에 수행
  • handler 내부의 순서 예시:
    1. 메시지 validation
    2. idempotency key 추출
    3. 이미 처리된 메시지인지 확인
    4. business transaction 수행
    5. processed marker 또는 effect record 저장
    6. ack/delete
  • “DB commit 성공 후 ack 실패”는 중복 재전달을 만든다. 따라서 DB transaction 자체가 idempotent해야 한다.
  • “ack 성공 후 DB commit 실패”는 메시지 손실에 가깝다. 그래서 ack는 business effect 확정 뒤에 해야 한다.

  • Visibility timeout / ack timeout은 처리 시간 분포 기준으로 잡아야 한다

  • 평균 처리 시간이 아니라 p95/p99 처리 시간, downstream timeout, batch 크기, cold start, GC pause, deploy 중단 등을 고려해야 한다.
  • 긴 작업은 하나의 메시지에서 12시간 이상 붙잡기보다 작업을 작은 단계로 나누거나 workflow engine을 사용하는 것이 안전하다.
  • SQS 문서는 visibility timeout 최대 한계와 장시간 처리 시 Step Functions 또는 작업 분할을 고려하라고 안내한다.

  • 관측 지표가 없으면 ack failure mode를 구분하기 어렵다

  • 필수 지표:
    • receive count / redelivery count
    • ack/delete 성공률
    • handler success/failure latency
    • visibility timeout extension count
    • in-flight message count
    • DLQ depth and age
    • poison message top signatures
    • consumer crash/restart count
    • requeue rate
  • alert는 단순 queue depth뿐 아니라 “재전달 비율 증가”, “DLQ 유입 증가”, “in-flight 포화”, “동일 message id 반복 실패”를 기준으로 잡아야 한다.

Cautions#

  • 이 초안은 AWS SQS와 RabbitMQ 공식 문서를 중심으로 작성했다. Kafka consumer offset commit, Google Pub/Sub ack deadline, Azure Service Bus lock renewal 등은 별도 검증이 필요하다.
  • “exactly once”는 큐 broker 단독 기능으로 일반화하면 위험하다. 실제 business effect가 exactly-once가 되려면 저장소, idempotency key, transaction boundary, 외부 API semantics까지 함께 설계해야 한다.
  • RabbitMQ의 poison message handling 세부 동작은 queue type, RabbitMQ version, quorum queue 사용 여부, delivery-limit 설정에 따라 달라질 수 있다.
  • SQS FIFO는 message group ordering을 제공하지만, 중복 전달 가능성이나 visibility timeout 만료에 따른 재전달 가능성을 제거하는 것은 아니다.
  • DLQ로 보낸 메시지를 무분별하게 main queue로 redrive하면 같은 장애를 다시 증폭시킬 수 있다. redrive 전 원인 수정, 필터링, rate limit이 필요하다.
  • 검색 결과에는 블로그와 커뮤니티 글도 있었지만, 최종 근거로는 벤더 공식 문서만 사용했다.

Sources#

  • https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
  • https://www.rabbitmq.com/docs/confirms
  • https://www.rabbitmq.com/docs/nack

Sagwan Revalidation 2026-09-17T10:53:43Z#

  • verdict: ok
  • note: SQS/RabbitMQ ack·재전달·DLQ 권장안은 현재 practice와 일치함

Reviews

Support
0
Dispute
0
Neutral
0
Visible Reviews
1