공부하기/Cloud

[AWS] AWS SQS(Simple Queue Service) 이해하기

다섯자두 2025. 4. 22. 17:46

AWS SQS란?

Simple Queue Service로, AWS에서 서비스하는 메시지 큐이다.

메시지 큐를 왜 사용할까?

  1. 하나의 API 요청에 동시에 수행되는 후처리 작업들이 많은 경우 ⇒ 응답 지연 최소화 및 시스템 간 결합도 감소 가능
    • 문제 상황
      • 응답 지연 문제 : API 내부에서 동기로 처리한다면 응답 대기 시간이 증가함 → UX 저하
      • 장애 전파 위험 : 외부 API 호출이 포함되는 경우, 서비스 하나에 장애가 나도 전체 기능 장애로 이어질 가능성이 높음
    • 해결
      • 한 API는 관련 작업만 처리하고, 동반되어야 하는 각 작업을 메시지로 만들어 큐에 넣음
      • 각각의 작업을 담당하는 Consumer가 큐에서 메시지를 비동기적으로 소비하여 처리함
    • 효과
      • 고객의 응답 대기 시간 감소
      • 후처리 시스템에 장애가 나도 메인 작업 자체는 정상 처리 가능
      • 개별 시스템을 유지보수/확장하기 쉬움 (서비스 간 결합도 감소)
  2. 순간적인 트래픽 폭주 상황 ⇒ 스케일링 및 트래픽 완충 버퍼 역할
    • 문제 상황
      • 서버 다운 위험 & 응답 지연 문제 : 특정 시간대에 요청이 동시에 몰릴 경우, 요청을 처리할 수 있는 서버 용량을 초과해버릴 수 있음
      • 오토 스케일링으로 서버 인스턴스를 늘릴 수는 있지만, 일단 한 서버로 들어온 모든 요청들은 그 서버가 모두 처리하므로 CPU, 메모리 등의 자원이 급격히 소모됨
      • 결과적으로 서버 과부하 → 응답 지연 혹은 서버 다운으로 요청 유실 위험 존재
    • 해결
      • 각 요청에 대한 작업(Job)을 큐에 넣고, 직렬 또는 병렬로 꺼내어 처리
      • 처리 로직을 담당하는 Worker를 여러 개 두고, 큐에서 메시지를 나누어 처리
      • 추후 트래픽이 늘어날 경우, Worker 수를 늘리면 Job을 나누어 수행할 수 있는 형태
    • 효과
      • 순간적으로 몰리는 트래픽을 큐가 흡수하여 완충 버퍼 역할 수행 → 시스템 안정성 증가
      • 서버는 큐에 메시지를 넣는 것까지만 처리하므로 즉각적인 응답 가능
      • 처리량 증가가 필요할 경우 큐 기반 구조로 스케일 아웃이 쉬움

메시지 전달 방식

메시지 큐에서 소비자(Consumer)에게 메시지를 전달하는 방식은 크게 두 가지로 나뉜다.

방식 설명 특징
Pull 방식 Consumer가 직접 메시지를 큐에서 가져감 (polling)
: Consumer가 직접 메시지를 확인하는 방식이다.
일반적인 큐 시스템 (ex. Kafka, SQS, RabbitMQ 기본 설정)
Push 방식 메시지 브로커가 메시지를 Consumer에게 자동 전달
: 메시지가 도착하면 Consumer에게 전달해준다.
이벤트 기반, 실시간 응답성이 중요할 때 사용 (ex. SNS, Webhook 구조 등)

SQS는 Pull 방식 기반 메시지 큐이다.

  • Consumer가 직접 ReceiveMessage API를 호출해야 메시지를 수신한다.
  • SNS/Lambda와 연동하면 Push처럼 사용할 수 있다. (⇒ 추후 공부 필요)

Standard Queue / FIFO Queue

SQS는 두 가지 종류의 큐를 지원한다.

항목 Standard Queue FIFO Queue
메시지 순서 보장 보장하지 않음 (Best-effort ordering) 보장함 (First-In-First-Out)
중복 메시지 가능성 있음 (At-least-once delivery) 없음 (Exactly-once processing)
처리량 (Throughput) 거의 무제한 제한적 (기본 300 TPS, 고처리량 모드에서 최대 3,000 TPS)
사용 사례 대규모 데이터 처리, 순서 중요하지 않은 작업 순서가 중요한 트랜잭션, 중복 허용되지 않는 작업
메시지 그룹화 지원하지 않음 MessageGroupId로 그룹화하여 순서 보장
비용 상대적으로 저렴 약간 더 비쌈

1. 메시지 순서 보장

  • Standard Queue는 메시지 순서를 보장하지 않으며, 순서 대신 처리량을 우선시한다.
    • 메시지가 큐에 도착한 순서와 관계없이 소비자에게 더 빨리 전달되는 메시지가 먼저 처리될 수 있다.
  • FIFO Queue는 메시지가 전송된 순서대로 정확히 처리되도록 보장한다.
    • MessageGroupId 단위로 순서대로 소비될 것을 보장한다.
    • 단일 그룹이라면 순차 처리, 다중 그룹이라면 그룹별 병렬 처리가 가능하다.

2. 중복 메시지 처리

  • Standard Queue는 최소 한 번 이상 메시지를 전달하므로, 중복 메시지가 발생할 수 있다.
    • At-least-once delivery : 최소한 한 번은 메시지가 전달될 것을 보장한다. 같은 메시지가 두 번 전달될 수 있다.
    • 이 때문에 어플리케이션 차원에서 중복 처리 방지 로직이 필요하다.
    • 어떻게 최소 한 번 이상 전달을 보장하는 지는 visibility timeout에서 설명된다.
  • FIFO Queue는 중복 메시지를 방지하기 위해 Deduplication ID를 사용하여 정확히 한 번만 처리한다.
    • 자동 중복 제거 : 메시지의 Deduplication ID가 같으면 5분 동안은 동일 메시지로 간주하고 무시된다.
    • MessageDeduplicationId를 명시하지 않고 Content-Based Deduplication을 활성화하면 메시지 본문을 기반으로 SHA-256 해시를 생성하여 중복 제거 ID로 사용한다. (내용이 같으면 중복 판단)
    • MessageDeduplicationId를 명시하지 않고 Content-Based Deduplication도 활성화하지 않으면 순서 보장은 되지 않는다.

3. 처리량

  • Standard Queue는 거의 무제한의 처리량을 제공하여 대규모 메시지 처리가 가능하다.
  • FIFO Queue는 기본적으로 초당 300건의 메시지를 처리할 수 있으며, 고처리량 모드에서는 최대 3,000 TPS까지 확장 가능하다.

4. 사용 사례

  • Standard Queue는 대규모 데이터 처리나 순서가 중요하지 않은 작업에 적합하다. (ex. 실시간 알림, 로그 수집, 이벤트 브로드캐스트 등)
  • FIFO Queue는 주문 처리, 금융 거래 등 순서와 중복 방지가 중요한 작업에 적합하다. (ex. 결제 순서 처리, 은행 이체, 상품 주문 처리 등)

Visibility Timeout

메시지를 한 Consumer가 받아간 후, 일정 시간 동안 다른 Consumer가 그 메시지를 다시 가져가지 못하게 하는 기간

At-Least-Once Delivery 보장 방식

기본 동작 원리

  • Consumer가 메시지를 수신(ReceiveMessage)했다고 해서 해당 메시지가 큐에서 바로 삭제되지 않는다.
  • 대신, visibility timeout 기간 동안 다른 Consumer에게 해당 메시지가 보이지 않도록 하여 소비되지 않도록 한다.
  • Consumer가 메시지를 성공적으로 처리한 후, 명시적으로 DeleteMessage API를 호출해야 메시지가 큐에서 제거된다.
ReceiveMessage → 작업 수행 → DeleteMessage

메시지 처리 실패 케이스

  • Consumer가 예외로 인해 죽거나 DeleteMessage를 호출하지 못한 경우
  • visibility timeout이 지나면 메시지는 다시 큐에서 visible 상태가 되어 다른 Consumer가 재처리 할 수 있게 된다.

결과적으로 보장되는 것

  • 동일한 메시지가 최소 한 번은 전달됨을 보장하지만, 상황에 따라 두 번 이상 전달될 수 있음도 허용한다.
  • 따라서 멱등성 보장이 중요하며 중복 메시지가 들어와도 동일한 결과가 되도록 로직을 설계할 필요가 있다.
[ReceiveMessage]
    ↓
[처리 중 → Visibility Timeout 기간 동안 잠금 상태]
    ↓
[DeleteMessage 호출 → 메시지 제거 완료]
       OR
[Timeout 초과 → 다시 visible 상태 → 재처리 가능성]

주의할 점

  • 메시지 처리 시간이 visibility timeout 시간보다 길다면
    • 메시지를 처리하는 데 시간이 오래 걸리는 작업의 경우 (ex. 이미지 인코딩, 외부 API 호출 등)
    • 설정한 Timeout 시간보다 처리 시간이 길어지면 메시지가 Visible 상태로 복원된다.
    • Consumer가 처리에 실패하지 않았음에도 다른 Consumer가 동일 메시지를 처리할 수 있다.
    • 가능한 해결책
      • 예상 처리 시간보다 여유 있는 timeout 설정
      • 처리 중일 때 ChangeMessageVisibility API를 호출하여 Timeout 연장이 가능하다.
  • 메시지를 다 처리한 후 DeleteMessage 호출이 누락된다면
    • Consumer가 메시지를 받아서 실제 로직(예: DB 저장, 외부 API 호출 등)은 수행하였으나 네트워크 예외, 서버 다운 등의 이유로 큐에서 삭제하지 못 한 경우
    • 가능한 해결책
      • 멱등성 보장 설계 : 어플리케이션 차원에서 메시지 ID를 기록하고 이미 처리된 메시지인지 확인

Retention Period

SQS 큐에 메시지가 저장될 수 있는 최대 기간
항목
기본값(Default) 4일 (345,600초)
설정 가능 범위 1분 ~ 14일 (60초 ~ 1,209,600초)
  • Retention Period 내에 메시지가 소비되지 않으면 자동으로 만료되고 큐에서 사라짐

주의 사항

  • 너무 짧으면? 장애 등으로 처리 지연 시 메시지가 만료되어 유실될 수 있음
  • 너무 길면? 오래된 메시지가 뒤늦게 소비되어 시점 불일치, 비정상 처리 발생 가능

🔗 Reference