공부하기/Cloud
[AWS] AWS SQS(Simple Queue Service) 이해하기
다섯자두
2025. 4. 22. 17:46
AWS SQS란?
Simple Queue Service로, AWS에서 서비스하는 메시지 큐이다.
메시지 큐를 왜 사용할까?
- 하나의 API 요청에 동시에 수행되는 후처리 작업들이 많은 경우 ⇒ 응답 지연 최소화 및 시스템 간 결합도 감소 가능
- 문제 상황
- 응답 지연 문제 : API 내부에서 동기로 처리한다면 응답 대기 시간이 증가함 → UX 저하
- 장애 전파 위험 : 외부 API 호출이 포함되는 경우, 서비스 하나에 장애가 나도 전체 기능 장애로 이어질 가능성이 높음
- 해결
- 한 API는 관련 작업만 처리하고, 동반되어야 하는 각 작업을 메시지로 만들어 큐에 넣음
- 각각의 작업을 담당하는 Consumer가 큐에서 메시지를 비동기적으로 소비하여 처리함
- 효과
- 고객의 응답 대기 시간 감소
- 후처리 시스템에 장애가 나도 메인 작업 자체는 정상 처리 가능
- 개별 시스템을 유지보수/확장하기 쉬움 (서비스 간 결합도 감소)
- 문제 상황
- 순간적인 트래픽 폭주 상황 ⇒ 스케일링 및 트래픽 완충 버퍼 역할
- 문제 상황
- 서버 다운 위험 & 응답 지연 문제 : 특정 시간대에 요청이 동시에 몰릴 경우, 요청을 처리할 수 있는 서버 용량을 초과해버릴 수 있음
- 오토 스케일링으로 서버 인스턴스를 늘릴 수는 있지만, 일단 한 서버로 들어온 모든 요청들은 그 서버가 모두 처리하므로 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 내에 메시지가 소비되지 않으면 자동으로 만료되고 큐에서 사라짐
주의 사항
- 너무 짧으면? 장애 등으로 처리 지연 시 메시지가 만료되어 유실될 수 있음
- 너무 길면? 오래된 메시지가 뒤늦게 소비되어 시점 불일치, 비정상 처리 발생 가능