AWS 07-1 큐와 알림 — SQS·SNS·SES·Amazon MQ
고친 사람 github-actions[bot]
쇼핑몰에서 주문 버튼을 누르면 결제 확인, 재고 차감, 주문 확인 메일, 포인트 적립, 창고 알림이 이어집니다. 이것을 전부 요청 하나 안에서 차례로 부르면 응답이 그만큼 늦고, 메일 서버 하나가 잠깐 멈춰도 주문 전체가 실패합니다. 사용자에게 필요한 답은 「주문이 접수됐다」 하나뿐인데 말입니다.
그래서 급하지 않은 일은 메시지(처리할 일을 적은 작은 데이터)로 남겨 두고 요청은 먼저 끝냅니다. 남겨 둔 메시지는 다른 프로그램이 제 속도로 꺼내 처리합니다. 이 편은 이렇게 일을 미뤄 두는 큐(queue) 서비스 SQS, 한 소식을 여러 곳에 퍼뜨리는 SNS, 사람에게 메일을 보내는 SES, 이미 쓰던 메시지 브로커(메시지를 받아 쌓아 두고 소비자에게 나눠 주는 서버 프로그램)를 그대로 옮겨 오는 Amazon MQ 를 봅니다. 끝에서는 하루 100만 건을 SQS 로 넘길 때와 브로커를 한 대 켜 둘 때의 한 달 값을 나란히 셈합니다. 요금과 한도는 전부 2026-09-27 서울(ap-northeast-2) 기준입니다.
지도
flowchart TD
START["요청 안에서<br/>다 하지 않을 일"] --> Q1{"받는 쪽이<br/>사람의 메일함인가"}
Q1 -- "그렇다" --> SES["SES"]
Q1 -- "아니다" --> Q2{"쓰던 브로커에<br/>붙는 코드가 있나"}
Q2 -- "있다" --> MQ["Amazon MQ"]
Q2 -- "없다" --> Q3{"받을 곳이<br/>여럿인가"}
Q3 -- "여럿" --> SNS["SNS<br/>필요하면 뒤에 SQS"]
Q3 -- "하나" --> SQS["SQS"]
첫 질문은 메시지를 받는 쪽이 사람의 메일함인지입니다. 프로그램이라면 이미 브로커에 붙어 도는 코드가 있는지부터 봅니다. 있으면 받을 곳이 하나든 여럿이든 Amazon MQ 로 옮기는 것이 가장 덜 고치는 길이고, 없으면 받을 곳이 하나인지 여럿인지가 SQS 와 SNS 를 가릅니다. 규칙에 따라 이벤트를 여러 서비스로 보내는 EventBridge 와 흐름을 짜는 Step Functions 는 07-2편(이벤트로 잇고 흐름을 짠다)에서, 쉬지 않고 흘러드는 데이터를 여러 번 다시 읽는 Kinesis·MSK 는 07-3편(쉬지 않고 흐르는 데이터)에서 다룹니다.
1. SQS — 줄을 세워 두고 나중에 꺼낸다
SQS(Simple Queue Service)에서 메시지를 넣는 쪽을 생산자(producer), 꺼내 처리하는 쪽을 소비자(consumer)라고 합니다. 생산자가 SendMessage 로 메시지를 넣으면 SQS 는 그것을 여러 가용 영역에 나눠 저장한 뒤에야 「받았다」고 답합니다. 소비자는 ReceiveMessage 로 메시지를 가져가고, 처리가 끝나면 DeleteMessage 로 지웁니다. SQS 가 소비자에게 밀어 주는 것이 아니라 소비자가 와서 가져가는 구조이고, 한 메시지는 한 소비자만 가져갑니다.
메시지는 기본 4일, 최대 14일 동안 큐에 남습니다. 이 기간을 보존 기간이라고 합니다. 크기는 최대 1 MiB 이고, 그보다 큰 것은 확장 클라이언트 라이브러리(자바·파이썬)가 본문을 S3 에 올리고 큐에는 그 위치만 넣는 방식으로 2 GB 까지 보냅니다(Amazon SQS message quotas).
가져갔는데 처리하다 죽으면
소비자가 메시지를 가져가자마자 큐에서 지워 버리면, 처리 도중 서버가 죽을 때 그 일은 사라집니다. 그래서 SQS 는 가져간 메시지를 지우지 않고 잠깐 숨깁니다. 이 숨기는 시간이 가시성 제한 시간(visibility timeout)이고 기본 30초, 최대 12시간입니다. 그 안에 소비자가 지우면 끝이고, 못 지우면 메시지가 다시 보여서 다른 소비자가 가져갑니다. 처리가 길어질 것 같으면 ChangeMessageVisibility 로 시간을 늘립니다. 다만 12시간은 처음 받은 때부터 세므로 늘려도 넘지 못합니다(Amazon SQS visibility timeout).
이 장치에는 반대편 위험이 있습니다. 메시지 내용 자체가 잘못돼 처리할 때마다 실패하면, 그 메시지는 숨었다 나타나기를 보존 기간 내내 되풀이합니다. 이런 메시지를 따로 빼 두는 큐가 배달 못 한 메시지 큐(DLQ, dead-letter queue)입니다. 원래 큐에 maxReceiveCount 를 정해 두면, 그 횟수만큼 받고도 지워지지 않은 메시지를 DLQ 로 옮깁니다. DLQ 는 원래 큐와 같은 계정·같은 리전에 있어야 하고, 원인을 고친 뒤에는 메시지를 원래 큐로 돌려보낼 수 있습니다. 기본 종류인 표준 큐(바로 아래에서 봅니다)는 DLQ 로 옮겨도 처음 넣은 시각으로 만료를 세므로, DLQ 의 보존 기간을 원래 큐보다 길게 잡아야 합니다(Using dead-letter queues in Amazon SQS).
빈 큐를 두드리는 값
ReceiveMessage 는 기본으로 짧은 폴링(short polling)입니다. SQS 서버 일부만 훑어 바로 답하므로, 큐가 비어 있으면 빈 응답이 오고 메시지가 있는데도 빈손으로 돌아올 때가 있습니다. 대기 시간을 1초 이상으로 주면 긴 폴링(long polling)이 되어, 모든 서버를 보고 메시지가 생길 때까지 최대 20초 기다렸다 답합니다. SQS 는 빈 응답도 요청 한 건으로 받으므로, 쉬지 않고 도는 소비자라면 긴 폴링이 곧 요금 절약입니다(Amazon SQS short and long polling).
표준 큐와 FIFO 큐
SQS 큐는 만들 때 두 종류 가운데 하나를 고릅니다. 표준 큐는 초당 API 호출을 사실상 제한 없이 받는 대신, 메시지가 적어도 한 번(at-least-once) 배달된다고만 약속합니다. 같은 메시지가 두 번 올 수 있고 순서도 가끔 뒤섞입니다. FIFO 큐(First-In-First-Out, 이름이 .fifo 로 끝납니다)는 메시지마다 메시지 그룹 ID 를 붙여 받고, 같은 그룹 안에서는 넣은 순서대로 하나씩 내줍니다. 그룹 안에서 앞 메시지가 처리 중이면 다음 메시지는 나오지 않습니다. 또 생산자가 같은 메시지를 5분 안에 다시 보내면 중복 제거 ID(내용의 SHA-256 해시로 자동으로 만들 수도 있습니다)로 알아보고 한 번만 넣습니다(Exactly-once processing in Amazon SQS).
FIFO 큐가 말하는 「정확히 한 번 처리」의 범위는 여기까지입니다. 큐에 중복이 들어가지 않는다는 약속이지, 소비자가 처리하고 지우기 전에 죽었을 때 다시 배달되지 않는다는 약속은 아닙니다. 가시성 제한 시간이 지나면 FIFO 에서도 같은 메시지가 다시 나옵니다. 순서를 지키는 값은 처리량으로 치릅니다. FIFO 는 API 동작별 초당 300건(10개씩 묶으면 메시지 3,000개)이 기본 한도이고, 높은 처리량 모드라는 설정을 켜면 서울에서 배치 없이 초당 2,400건, 묶으면 초당 24,000개까지 올라갑니다(Amazon SQS message quotas). 두 큐는 결국 순서·중복·처리량·값에서 서로 반대편에 섭니다.
| 표준 큐 | FIFO 큐 | |
|---|---|---|
| 순서 | 최선을 다할 뿐, 가끔 뒤섞인다 | 메시지 그룹 안에서 넣은 순서대로 |
| 큐에 들어가는 횟수 | 같은 메시지가 두 번 들어갈 수 있다 | 5분 안의 중복 전송을 걸러 한 번만 들어간다 |
| 처리 도중 죽었을 때 재배달 | 있다 | 있다 |
| 처리량 | 사실상 제한 없음 | 기본 초당 300건, 높은 처리량 모드로 올린다 |
| 요청 요금(100만 건당) | $0.40 | $0.50 |
그래서 기본은 표준 큐로 두고 소비자를 멱등으로 짜며, 같은 그룹 안에서 순서가 뒤집히면 결과가 틀어지는 일(계좌별 입출금 같은)만 FIFO 큐로 보냅니다.
FIFO 를 고르면 DLQ 에서 선택이 하나 생깁니다. 한 메시지가 계속 실패하면 그 뒤의 같은 그룹 메시지는 모두 멈춰 기다립니다. 그 메시지를 DLQ 로 빼면 막힘은 풀리지만, 뒤 메시지가 앞 메시지보다 먼저 처리되어 순서 보장이 깨집니다. 그룹이 멈추는 것과 순서가 깨지는 것 가운데 무엇을 견딜지 정해 두어야 합니다.
Lambda 에 연결하기
소비자를 서버로 띄워 두지 않고 Lambda 함수로 두는 경우가 많습니다. 이벤트 소스 매핑(event source mapping)을 만들면 Lambda 가 큐를 읽어 메시지를 묶음으로 함수에 넘기고, 함수가 성공하면 그 묶음을 지웁니다. 묶음 크기는 표준 큐 최대 10,000개, FIFO 큐 최대 10개입니다. 표준 큐에서 10개를 넘기려면 묶음을 채우려고 기다리는 시간인 배치 창(MaximumBatchingWindowInSeconds)을 1초 이상 줘야 합니다. 표준 큐는 메시지가 쌓이면 함수를 동시에 띄우는 개수(동시 실행)를 분당 300개씩 늘려 기본 최대 1,250개까지 갑니다(Creating and configuring an Amazon SQS event source mapping).
설정할 때 세 가지를 맞춥니다. 큐의 가시성 제한 시간은 함수 제한 시간의 6배 이상(배치 창을 쓰면 그 시간을 더해서)으로 잡습니다. 함수가 스로틀링(동시성이 모자라 거절당하는 것)에 걸렸을 때 다시 시도할 여유입니다. 같은 까닭으로 원래 큐의 maxReceiveCount 는 5 이상으로 잡습니다. 스로틀링으로 몇 번 돌아온 멀쩡한 메시지가 DLQ 로 가 버리지 않게 하는 것입니다. 그리고 묶음 안의 한 건만 실패해도 기본으로는 묶음 전체가 큐로 돌아가므로, 실패한 메시지만 돌려보내는 부분 배치 응답(ReportBatchItemFailures)을 켭니다. 이벤트 소스 매핑도 적어도 한 번 처리이므로 함수는 같은 메시지를 두 번 받아도 결과가 같게 멱등(idempotent)으로 짜야 합니다(Using Lambda with Amazon SQS). Lambda 자체의 요금·한도는 Lambda 편(01-3)에서 봤습니다.
요금
SQS 는 API 요청 수로만 받습니다. 보내기·받기·지우기·빈 응답까지 모든 API 동작이 요청 한 건입니다. 요청 하나에 메시지를 최대 10개까지 묶을 수 있지만, 본문은 64 KB 마다 요청 한 건으로 칩니다(Amazon SQS Pricing).
SQS · 서울 · 2026-09-27
표준 큐 100만 요청당 $0.40
FIFO 큐 100만 요청당 $0.50
월 무료 요청 100만 건 (모든 리전 합산, 매달)
64 KB 단위 1 MiB 짜리 요청 하나 = 16건
전송량 같은 리전 안에서 넣고 빼면 0원
값은 요청 수에만 붙고 쉬는 동안에는 빈 응답 말고 나가는 돈이 없습니다. 그러니 SQS 를 쓸지 가르는 것은 값보다 앞에서 본 배달 방식, 곧 소비자가 가져가고 한 메시지는 한 소비자만 받으며 적어도 한 번 온다는 성질입니다.
| 이럴 때 맞다 | 이럴 때 안 맞다 | 대신 치르는 것 |
|---|---|---|
| 요청은 먼저 끝내고 무거운 뒷일(썸네일·메일·집계)을 나중에 할 때 | 호출한 쪽이 결과를 곧바로 받아야 할 때 | 처리 결과를 따로 알려 줄 길을 만들어야 한다 |
| 한 종류의 일을 소비자 여럿이 나눠 처리할 때 | 한 메시지를 여러 시스템이 각자 받아야 할 때(→ SNS) | 한 메시지는 한 소비자만 가져가고, 지우면 사라진다 |
| 두 번 처리돼도 결과가 같게 짤 수 있는 일(표준 큐) | 중복이나 순서 뒤섞임을 견딜 수 없는 일 | 소비자를 멱등으로 짜야 한다 |
| 그룹 안 순서가 뒤집히면 안 되는 일(FIFO 큐) | 순서와 상관없이 초당 수천 건을 넘게 쏟아내는 일 | 처리량 한도와 비싼 요청 값, 한 건이 막히면 그룹이 멈춘다 |
소비자가 처리한 메시지를 나중에 다시 처음부터 읽어야 한다면 SQS 로는 안 되고 Kinesis·MSK 같은 스트림 서비스가 필요합니다.
2. SNS — 한 번 게시해 여러 곳에 배달한다
주문 하나가 들어왔을 때 창고 시스템, 포인트 시스템, 분석 파이프라인이 모두 그 소식을 받아야 한다고 해 봅니다. 주문 서비스가 셋에게 각각 보내면 네 번째가 생길 때마다 주문 서비스 코드를 고쳐야 합니다. SNS(Simple Notification Service)는 이 관계를 뒤집습니다. 주문 서비스는 토픽(topic)이라는 이름 붙은 게시판에 메시지를 한 번 게시(publish)하고, 받고 싶은 쪽이 그 토픽을 구독(subscribe)합니다. 이 방식을 게시·구독(pub/sub)이라고 합니다. SQS 와 달리 SNS 는 메시지를 쌓아 두지 않고 구독자에게 곧바로 밀어 줍니다.
구독자로는 SQS 큐, Lambda 함수, HTTP(S) 주소, 이메일, SMS, 모바일 푸시, Data Firehose 를 걸 수 있습니다. 표준 토픽 하나에 구독은 최대 1,250만 개이고, 구독마다 필터 정책(메시지 속성을 보고 받을 것만 고르는 규칙)을 붙일 수 있습니다. 메시지 크기는 기본 256 KiB 이고, 토픽 속성 MaximumMessageSize 로 1 MiB 까지 올릴 수 있습니다. 256 KiB 를 넘기면 구독자는 SQS·Lambda·Firehose 만 되고 구독은 토픽당 100개까지입니다(Amazon SNS 1 MiB 지원 발표). 서울에서 게시는 계정당 초당 1,500개(표준 토픽)까지이고 늘려 달라고 요청할 수 있습니다. 이메일 구독은 초당 10건으로 고정돼 있어 늘릴 수 없습니다(Amazon Simple Notification Service endpoints and quotas).
SNS 뒤에 SQS 를 붙이는 팬아웃
SNS 가 곧바로 Lambda 나 HTTP 주소로 밀어 주면, 받는 쪽이 잠깐 멈춘 동안 온 메시지는 재시도에 기대야 합니다. 그래서 흔한 구성은 구독자마다 SQS 큐를 하나씩 두는 것입니다. 한 메시지가 여러 큐로 퍼져 나가서 팬아웃(fan-out)이라고 부릅니다(Fanout Amazon SNS notifications to Amazon SQS queues for asynchronous processing).
flowchart TD
ORD["주문 서비스"] -->|"게시 1번"| T["SNS 토픽<br/>주문 생성"]
T --> Q1["SQS 큐<br/>창고"]
T --> Q2["SQS 큐<br/>포인트"]
T --> Q3["SQS 큐<br/>분석"]
Q1 --> W1["창고 소비자"]
Q2 --> W2["포인트 Lambda"]
Q3 --> W3["분석 배치"]
주문 서비스는 토픽 하나만 알고, 각 소비자는 자기 큐에서 꺼내 씁니다. 포인트 시스템이 한 시간 멈춰도 메시지는 그 큐에 쌓여 기다리고, 창고 쪽은 영향을 받지 않습니다. 새 소비자가 생기면 큐를 하나 더 만들어 구독시키면 되고 주문 서비스는 고치지 않습니다. 큐마다 SNS 가 메시지를 넣도록 허락하는 큐 정책(접근 권한 규칙)을 붙여야 합니다.
순서와 중복 제거가 필요하면 FIFO 토픽을 씁니다. SQS FIFO 처럼 메시지 그룹 안의 순서를 지키고 중복을 거르며, 뒤에 SQS FIFO 큐를 붙이면 그 성질이 끝까지 이어집니다. 표준 토픽에는 없는 보관 기능도 있어서, 메시지를 보관해 두었다가 구독자에게 다시 보내 줄 수 있습니다. 대신 구독자는 SQS 큐(FIFO·표준)만 되고 이메일·SMS·HTTP 는 안 됩니다. 토픽당 구독은 100개, 메시지 그룹당 초당 300개가 한도입니다(Amazon SNS message delivery for FIFO topics).
요금
SNS 는 게시한 요청 수와, 받는 쪽 종류에 따른 배달 건수로 받습니다. 표준 토픽은 게시 본문 64 KB 마다 요청 한 건입니다(Amazon SNS pricing).
SNS 표준 토픽 · 서울 · 2026-09-27
게시(API 요청) 100만 건당 $0.50 월 100만 건 무료
배달 → SQS·Lambda 건당 0원 (전송량만 따로)
배달 → HTTP(S) 10만 건당 $0.06 월 10만 건 무료
배달 → 이메일 10만 건당 $2.00 월 1,000건 무료
배달 → 모바일 푸시 100만 건당 $0.50 월 100만 건 무료
SNS FIFO 토픽 · 서울
게시 요청 100만 건당 $0.36
게시 본문 GB 당 $0.0204
구독자로 배달 100만 건당 $0.012 + GB 당 $0.0012
팬아웃으로 SQS 에 배달하는 값은 0원이라, 실제 청구는 게시 요청과 각 큐에서 일어나는 SQS 요청이 대부분입니다. 값보다 판단을 가르는 것은 두 가지입니다. SNS 는 지금 붙어 있는 구독자에게 밀어 주고 끝이라 메시지를 들고 있지 않고, 사람에게 가는 이메일 구독은 한도가 낮습니다.
| 이럴 때 맞다 | 이럴 때 안 맞다 | 대신 치르는 것 |
|---|---|---|
| 한 사건을 여러 시스템이 각자 받아야 할 때(뒤에 SQS 를 붙인다) | 받는 쪽이 하나뿐일 때(→ SQS 만으로 충분) | 토픽·구독·큐 정책이 한 겹 더 늘어난다 |
| 운영 알람을 운영자 메일과 HTTP 도구에 동시에 알릴 때 | 고객에게 메일을 대량으로 보낼 때(→ SES) | 이메일 구독은 초당 10건 고정 한도다 |
| 지금 구독 중인 곳에만 알리면 되는 일 | 나중에 붙은 소비자가 지난 메시지까지 받아야 할 때 | 표준 토픽은 보관하지 않는다. 다시 보내기는 FIFO 토픽의 보관 기능뿐이다 |
이벤트 내용을 보고 규칙에 따라 여러 AWS 서비스로 나눠 보내거나 SaaS 에서 오는 이벤트까지 한 곳에서 다루려면 EventBridge 가 그 일을 맡습니다.
3. SES — 사람의 메일함으로 보낸다
가입 확인, 비밀번호 재설정, 주문 영수증처럼 애플리케이션이 사람에게 보내는 메일은 SES(Simple Email Service)가 맡습니다. SNS 이메일 구독이 초당 10건에 묶인 운영 알람용이라면, SES 는 첨부까지 갖춘 메일을 API 나 SMTP 로 대량으로 보냅니다.
처음 만든 계정은 리전마다 샌드박스(sandbox, 시험용으로 제한을 건 상태)에 들어갑니다. 샌드박스에서는 검증한 주소와 도메인으로만 보낼 수 있고, 24시간에 200통, 초당 1통이 한도입니다. 콘솔에서 운영 전환을 요청하면서 보낼 메일 종류(거래용·마케팅)와 웹사이트, 반송·신고 처리 방법을 적어 내면, 보통 24시간 안에 첫 답이 옵니다. 전환한 뒤에도 보내는 쪽 주소(From)나 그 도메인은 계속 검증돼 있어야 합니다(Request production access).
스팸함에 안 가려면 — 발신 도메인 인증
받는 메일 서버는 이 메일이 정말 그 도메인에서 온 것인지부터 따집니다. 도메인의 DNS 에 세 가지를 적어 둡니다.
- SPF(Sender Policy Framework) — 이 도메인 이름으로 메일을 보내도 되는 서버 목록을 DNS TXT 레코드에 적어 둡니다
- DKIM(DomainKeys Identified Mail) — 보내는 메일 머리에 전자 서명을 붙이고, 받는 쪽이 DNS 에 올린 공개 키로 확인합니다. SES 의 Easy DKIM 을 켜면 SES 가 알아서 서명합니다
- DMARC(Domain-based Message Authentication, Reporting and Conformance) — 받는 사람이 보는 From 주소의 도메인이 SPF 나 DKIM 가운데 적어도 하나와 맞는지 확인하고, 안 맞는 메일을 어떻게 할지(
none·quarantine·reject) 정합니다
여기서 메일 한 통에 주소가 둘이라는 점을 알아야 합니다. 받는 사람 화면에 보이는 From 과, 반송 메일이 돌아가는 봉투 주소(MAIL FROM)입니다. SPF 는 봉투 주소의 도메인을 검사하는데, SES 는 기본으로 봉투 주소에 SES 자신의 도메인을 씁니다. 그러면 SPF 는 통과해도 From 의 도메인과 맞지 않아 DMARC 에는 보탬이 되지 않습니다. 봉투 주소를 내 도메인으로 바꾸는 사용자 지정 MAIL FROM 을 세워야 SPF 도 DMARC 를 거듭니다. DMARC 정책은 p=none 으로 보고서만 받으며 시작해 quarantine, reject 순서로 조입니다(Complying with DMARC authentication protocol in Amazon SES).
반송과 스팸 신고를 관리해야 계정이 산다
SES 는 여러 고객이 같은 발송 설비를 나눠 쓰므로, 한 계정이 스팸을 뿌리면 다른 고객의 전달률까지 떨어집니다. 그래서 두 비율을 봅니다. 반송률은 없는 주소처럼 영구히 실패한 메일의 비율이고, 스팸 신고율은 받은 사람이 「스팸 신고」를 누른 비율입니다. 반송률은 2% 아래, 신고율은 0.1% 아래로 유지해야 합니다. 반송률이 5% 에 이르거나 신고율이 0.1% 에 이르면 SES 가 계정을 검토 중으로 돌립니다. 신고율은 유지선과 검토선이 같은 0.1% 라서, 선을 넘는 순간 바로 검토 대상입니다. 검토 중에도 발송은 되지만 그 기간에 비율을 낮추지 못하면 발송이 멈출 수 있고, 반송률 10%·신고율 0.5% 에 이르면 곧바로 발송을 멈출 수 있습니다(Amazon SES Sending review process FAQs). 반송·신고 알림을 SNS 로 받아 그 주소를 목록에서 바로 지우는 처리를 붙이는 것이 보통입니다.
요금
SES 는 받는 사람 수로 받습니다. 전달률 관리 기능을 얹는 요금제도 있는데, Essentials 는 월 기본료 없이 1,000통당 $0.16 을 받고, Pro(월 $105)와 Enterprise(월 $500)는 월정액까지 받습니다. 여기서는 기본 요금만 봅니다.
SES 기본 요금 · 서울 · 2026-09-27
발송 1,000통당 $0.10 (받는 사람 1명 = 1통)
첨부 GB 당 $0.12
전용 IP IP 하나에 월 $24.95 (쓸 때만)
- SES 에는 따로 주는 월 무료 건수가 없습니다. 대신 새 계정이 받는 AWS 프리 티어 크레딧(최대 $200, 가입 후 6개월)을 SES 에도 쓸 수 있습니다(Amazon SES pricing)
한 달에 10만 통이면 $10 입니다. 값은 싸지만 도메인 인증, 평판 관리, 샌드박스 심사는 내가 떠안습니다.
| 이럴 때 맞다 | 이럴 때 안 맞다 | 대신 치르는 것 |
|---|---|---|
| 가입 확인·영수증 같은 거래용 메일을 대량으로 보낼 때 | 운영자 몇 명에게 가는 알람 메일(→ SNS 이메일 구독이 간단) | SPF·DKIM·DMARC 와 MAIL FROM 을 DNS 에 직접 세워야 한다 |
| 동의를 받은 수신자에게 소식지를 보낼 때 | 사거나 오래 묵은 주소 목록으로 보낼 때 | 반송·신고율이 선을 넘으면 계정 발송이 멈춘다 |
| 출시 전에 운영 전환을 미리 받아 둘 수 있을 때 | 오늘 만든 계정으로 당장 고객에게 보내야 할 때 | 운영 전환 심사를 먼저 통과해야 한다 |
4. Amazon MQ — 쓰던 브로커를 그대로 옮긴다
SQS·SNS 는 AWS 만의 API 로 씁니다. 그런데 이미 메시지 브로커를 쓰던 시스템이 있습니다. 자바 진영의 표준 API 인 JMS 로 짠 애플리케이션, AMQP(메시지 브로커와 주고받는 표준 프로토콜)나 MQTT(IoT 기기용 가벼운 메시징 프로토콜)·STOMP(텍스트 기반 단순 메시징 프로토콜)로 브로커에 붙는 장비가 그렇습니다. 이런 시스템을 SQS 로 옮기려면 메시징 코드를 다시 짜야 합니다.
Amazon MQ 는 오픈소스 브로커 두 가지, ActiveMQ(Classic)와 RabbitMQ 를 관리형으로 띄워 줍니다. 설치·패치·버전 올리기·장애 조치를 AWS 가 맡고, 애플리케이션은 접속 주소만 바꿔 쓰던 코드 그대로 붙습니다(What is Amazon MQ?). ActiveMQ 브로커는 OpenWire·AMQP 1.0·STOMP·MQTT·WebSocket 과 JMS 를, RabbitMQ 브로커는 AMQP 0-9-1 을 받습니다.
브로커는 인스턴스로 돕니다. 한 대만 도는 단일 인스턴스, 다른 가용 영역에 대기 브로커를 두는 활성/대기(ActiveMQ), 세 노드를 묶은 클러스터(RabbitMQ) 가운데 고릅니다. 인스턴스 종류에는 AWS 가 붙인 권장 용도가 있습니다. ActiveMQ 의 mq.t3.micro(vCPU 2 · 1 GiB)와 RabbitMQ 의 mq.m7g.medium(vCPU 1 · 4 GiB)은 평가용이고, RabbitMQ 운영용으로 권하는 가장 작은 것은 mq.m7g.large(vCPU 2 · 8 GiB)입니다(Amazon MQ for RabbitMQ broker instance types · Amazon MQ for ActiveMQ broker instance types).
요금
SQS 와 가장 크게 다른 점은 메시지가 없어도 브로커가 켜져 있는 시간만큼 돈이 나간다는 것입니다. 한 달은 730시간으로 셉니다.
Amazon MQ · 서울 · 2026-09-27 · 한 달 730시간
ActiveMQ mq.t3.micro 단일(평가용) $0.0338/시간 → $24.67
RabbitMQ mq.m7g.medium 단일(평가용) $0.1682/시간 → $122.79
RabbitMQ mq.m7g.large 단일 $0.336/시간 → $245.28
ActiveMQ mq.m5.large 활성/대기 $0.708/시간 → $516.84
RabbitMQ mq.m7g.large 3노드 클러스터 $1.008/시간 → $735.84
저장 ActiveMQ EFS GB-월 $0.33 · EBS GB-월 $0.114
RabbitMQ EBS GB-월 $0.114
전송 브로커끼리 가용 영역을 넘어 전달할 때 GB 당 $0.01 (방향마다)
RabbitMQ 클러스터 안의 전송은 0원
- 요금은 초 단위로 셉니다. Amazon MQ 에는 따로 주는 무료 시간이 없습니다. 새 계정의 프리 티어 크레딧은 쓸 수 있습니다(Amazon MQ pricing)
정리하면 코드를 안 고치는 대가로 브로커를 늘 켜 두어야 하고, 크기와 이중화도 내가 고릅니다.
| 이럴 때 맞다 | 이럴 때 안 맞다 | 대신 치르는 것 |
|---|---|---|
| JMS·AMQP·MQTT 로 짠 기존 시스템을 코드 수정 없이 옮길 때 | 새로 짜는 애플리케이션(→ SQS·SNS 가 싸고 관리할 것이 없다) | 메시지가 0건이어도 인스턴스 시간 요금이 나간다 |
| 처리량이 고르고 미리 가늠할 수 있을 때 | 처리량이 들쭉날쭉해 자동으로 늘고 줄어야 할 때 | 인스턴스 크기를 내가 골라야 하고, 넘치면 크기를 올려야 한다 |
| 평가·개발용이라 한 대가 멈춰도 될 때(단일 인스턴스) | 가용 영역 하나가 죽어도 버텨야 할 때 | 클러스터로 가면 RabbitMQ 는 단일 $245.28 이 $735.84 로 3배가 된다 |
Kafka 로 짠 시스템을 옮길 때는 Amazon MQ 가 아니라 MSK(Managed Streaming for Apache Kafka)를 씁니다(07-3편).
5. 하루 100만 건 — SQS 로 넘길까, 브로커를 켤까
하루 100만 건의 뒷일을 30일 동안 소비자에게 넘긴다고 해 봅니다. 메시지 하나는 6 KB 안팎이라 10개를 묶어도 64 KB 를 넘지 않는다고 둡니다. SQS 쪽은 메시지마다 보내기·받기·지우기 세 요청이 들고, 표준 큐를 씁니다. 브로커 쪽은 4절의 요금을 그대로 씁니다.
SQS 표준 큐 · 서울 · 30일
메시지 100만 × 30 = 3,000만 건
하나씩 보낼 때
요청 3,000만 × 3 = 9,000만 건
요금 (9,000만 − 100만) × $0.40/100만 = $35.60
10개씩 묶을 때 (보내기·받기·지우기 모두)
요청 9,000만 ÷ 10 = 900만 건
요금 (900만 − 100만) × $0.40/100만 = $3.20
※ 묶음이 늘 10개로 차고 64 KB 를 넘지 않을 때의 하한
빈 응답 20초 긴 폴링 연결 하나가
2,592,000초 ÷ 20 = 129,600건 ≈ $0.05
Amazon MQ · 서울 · 730시간 (4절 값)
mq.t3.micro ActiveMQ 단일(평가용) $24.67 + 저장
mq.m7g.large RabbitMQ 단일(운영용) $245.28 + 저장
$3.20 은 하한입니다. 묶음 전체가 64 KB 를 넘으면 그만큼 요청 건수로 다시 셉니다. 받기 쪽 묶음도 큐에 10개가 쌓여 있어야 꽉 찹니다. 긴 폴링은 메시지가 하나만 있어도 바로 돌려주기 때문입니다. 지우기는 본문이 없어 늘 10분의 1이 됩니다.
하나씩 보내도 SQS 는 월 $35.60 으로, 운영용으로 권하는 가장 작은 브로커($245.28)의 약 7분의 1입니다. 평가용 mq.t3.micro($24.67)가 하나씩 보내는 SQS 보다 싸게 보이지만, 메모리 1 GiB 짜리 평가용 한 대라 그 한 대가 서면 큐 전체가 멈춥니다. SQS 는 여러 가용 영역에 나눠 저장하는 값까지 이 요금에 들어 있습니다.
건수가 늘면 셈이 뒤집힐 수 있습니다. 브로커는 같은 크기로 버티는 동안 값이 그대로이고, SQS 는 요청 수만큼 늘어납니다. 위 셈을 그대로 늘리면 하나씩 보낼 때는 하루 약 700만 건, 늘 꽉 차게 묶을 때는 하루 약 7,000만 건에서 SQS 가 $245.28 을 넘습니다. 건수가 그 근처이고 이미 브로커용 코드가 있다면 다시 셈해 볼 만합니다.
이럴 땐 무엇
| 상황 | 서비스 | 이유 |
|---|---|---|
| 업로드 뒤 썸네일 생성처럼 무거운 뒷일을 미룬다 | SQS 표준 큐 + Lambda | 요청은 먼저 끝내고, 쉬는 동안 값이 거의 없다 |
| 계좌별 입출금처럼 순서가 뒤집히면 안 된다 | SQS FIFO 큐 | 메시지 그룹 안의 순서와 5분 중복 제거 |
| 주문 생성을 창고·포인트·분석이 각자 받는다 | SNS 토픽 → SQS 큐 여럿 | 팬아웃. SQS 배달은 0원이고 소비자끼리 서로 영향이 없다 |
| 서버 장애 알람을 운영자 메일과 사내 HTTP 알림 주소로 | SNS 표준 토픽 | 이메일·HTTP 구독을 한 토픽에 건다 |
| 가입 확인·영수증 메일 | SES | 1,000통당 $0.10, 대신 도메인 인증과 반송 관리 |
| JMS 로 짠 사내 시스템을 AWS 로 옮긴다 | Amazon MQ(ActiveMQ) | JMS 코드를 접속 주소만 바꿔 그대로 붙인다 |
| AMQP 로 RabbitMQ 를 쓰던 서비스를 옮긴다 | Amazon MQ(RabbitMQ) | AMQP 0-9-1 클라이언트를 그대로 붙인다 |
자주 붙는 서비스는 Lambda(소비자), CloudWatch(큐 길이·DLQ 알람), IAM(큐·토픽 정책), KMS(메시지 암호화), EventBridge·Step Functions(07-2편), Route 53(SES 도메인 인증 레코드)입니다.
한 장 요약
큐와 알림은 요청 안에서 다 하지 않을 일을 떼어 내는 도구입니다. SQS·SNS 는 FIFO 를 골라도 다시 배달될 수 있으니 소비자를 멱등으로 짜는 것이 먼저입니다. 값은 SQS·SNS 가 쓴 만큼, Amazon MQ 는 켜 둔 만큼이라 하루 100만 건이면 SQS(월 $35.60)가 운영용 브로커(월 $245.28)보다 쌉니다.
관련 항목
일을 미루고 알리는 같은 갈래
Amazon SQS · Amazon SNS · Amazon SES · Amazon MQ · Amazon EventBridge · AWS Step Functions · Amazon Kinesis Data Streams · Amazon MSK
SQS 를 이루는 장치
메시지 큐 · 가시성 제한 시간 · 배달 못 한 메시지 큐 · 긴 폴링 · FIFO 큐 · 메시지 그룹 ID · 중복 제거 ID · 공정 큐 · SQS 확장 클라이언트 라이브러리
큐를 쓰는 쪽이 지켜야 하는 성질
적어도 한 번 전달 · 정확히 한 번 처리 · 멱등성 · 생산자-소비자 패턴 · 비동기 처리 · 백프레셔
SQS 를 읽고 쓰는 계산 쪽
AWS Lambda · 이벤트 소스 매핑 · 부분 배치 응답 · 스로틀링 · ECS · EC2
SNS 가 메시지를 퍼뜨리는 방식
게시·구독 · 팬아웃 · SNS 토픽 · SNS FIFO 토픽 · 구독 필터 정책 · 모바일 푸시 · AWS End User Messaging
SES 메일을 받는 쪽이 믿게 하는 장치
SPF · DKIM · DMARC · MAIL FROM 도메인 · 반송률 · 스팸 신고율 · SES 샌드박스 · SMTP · Route 53
Amazon MQ 가 관리형으로 띄우는 브로커와 프로토콜
메시지 브로커 · Apache ActiveMQ · RabbitMQ · JMS · AMQP · MQTT · STOMP · Apache Kafka
이 서비스들의 요금과 한도를 이루는 단위
AWS 프리 티어 · 가용 영역 · Service Quotas · CloudWatch · AWS KMS · IAM 정책