SNS + SQS — メッセージング
概要
SNS (Simple Notification Service) と SQS (Simple Queue Service) は AWS の 2 大メッセージング基盤。 システム間を疎結合にする、非同期処理を導入する、再試行や負荷平準化を行う、といった目的で使い分けます。
- SNS = Pub/Sub。1 メッセージを複数の Subscriber に同時配信。
- SQS = キュー。1 メッセージを 1 Consumer が処理(複数 Consumer なら早い者勝ち)。
両者を組み合わせる「Fanout パターン」(SNS → 複数 SQS)が定番。
SNS の主な機能
- Topic — メッセージの送信先カテゴリ。Standard と FIFO の 2 種類。
- Subscription — Topic を受信する宛先。Email / SMS / HTTPS / Lambda / SQS / Kinesis Firehose。
- FIFO Topic — 順序保証 + 重複排除。SQS FIFO とセットで使う。
- Filter Policy — Subscriber 側でメッセージ属性を見て受信可否を判定。
- Mobile Push — APNs / FCM 経由でアプリ通知配信。
SQS の主な機能
- Standard Queue — 高スループット、順序保証なし、稀に重複あり (At-Least-Once)。
- FIFO Queue — 順序保証 + Exactly-Once。1 グループ 300 TPS 上限。
- Visibility Timeout — Consumer が message を取った後、他 Consumer に見えなくなる期間。
- Dead Letter Queue (DLQ) — 一定回数失敗したメッセージを別キューに退避。
- Long Polling — 受信を最大 20 秒待つことで API 呼び出し回数削減。
- Lambda トリガ — SQS にメッセージが入ると自動的に Lambda が呼ばれる。
- Delay Queue / Message Timer — 配信を一定時間遅延。
SNS vs SQS の使い分け
| シナリオ | 選択 | 理由 |
|---|---|---|
| 1 メッセージ → 複数の処理 | SNS (+ SQS) | Fanout が前提 |
| 負荷平準化したい | SQS | Consumer が自分のペースで pull |
| 順序保証が必要 | FIFO Topic + FIFO Queue | Standard では順序保証無し |
| 失敗リトライ + DLQ | SQS | DLQ 機能で再処理を制御 |
| Email / Mobile 通知 | SNS | SNS が Subscriber 種別豊富 |
| CloudWatch Alarm の通知先 | SNS | Alarm から SNS Topic へが標準 |
使うべきパターン
- 非同期処理 — API → SQS → Lambda で「重い処理を後回し」。
- マイクロサービス間連携 — SNS Fanout で複数サービスへ疎結合通知。
- 監視通知 — CloudWatch Alarms → SNS → Email。
- バッチ処理の入口 — S3 イベント → SNS → 複数 SQS → 各 Lambda。
使わない方が良いパターン
- 低レイテンシ ms 級リアルタイム — EventBridge / Kinesis Streams を検討。
- 大量ストリーム処理 (秒間数万) — Kinesis Data Streams の方が向く。
- WebSocket 双方向 — API GW WebSocket / IoT Core が適切。
Terraform 最小サンプル(SNS Fanout + SQS + DLQ)
# SNS Topic
resource "aws_sns_topic" "events" {
name = "events"
}
# DLQ
resource "aws_sqs_queue" "worker_dlq" {
name = "worker-dlq"
}
# Worker Queue
resource "aws_sqs_queue" "worker" {
name = "worker"
visibility_timeout_seconds = 60
message_retention_seconds = 1209600 # 14 日
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.worker_dlq.arn
maxReceiveCount = 3
})
}
# SQS が SNS を購読
resource "aws_sns_topic_subscription" "worker" {
topic_arn = aws_sns_topic.events.arn
protocol = "sqs"
endpoint = aws_sqs_queue.worker.arn
}
# SNS から SQS への送信を許可する Queue Policy
resource "aws_sqs_queue_policy" "worker" {
queue_url = aws_sqs_queue.worker.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "sns.amazonaws.com" }
Action = "sqs:SendMessage"
Resource = aws_sqs_queue.worker.arn
Condition = {
ArnEquals = { "aws:SourceArn" = aws_sns_topic.events.arn }
}
}]
})
}
# Lambda トリガ
resource "aws_lambda_event_source_mapping" "worker" {
event_source_arn = aws_sqs_queue.worker.arn
function_name = aws_lambda_function.worker.arn
batch_size = 10
}
用語集
- Topic / Subscription
- SNS の 2 主要要素。Topic = 送信先カテゴリ、Subscription = 受信先設定。
- Pub/Sub
- Publish/Subscribe パターン。1 メッセージを複数の Subscriber に同時配信する設計。
- Fanout
- SNS → 複数 SQS への配信パターン。Producer は SNS に送るだけで複数の処理パイプを起動可能。
- Standard / FIFO
- Standard = 高スループット・順序保証なし。FIFO = 順序保証 + Exactly-Once、ただしスループット制限あり。
- Visibility Timeout
- Consumer が message を取った後、他 Consumer に見えなくする期間。Lambda timeout より長くする。
- Dead Letter Queue (DLQ)
- maxReceiveCount を超えたメッセージを退避する別キュー。失敗メッセージの可視化と手動再処理に。
- Long Polling
- SQS の受信を最大 20 秒待つことで API 呼び出し回数を削減する仕組み。
- Filter Policy
- SNS Subscriber 側でメッセージ属性を見て受信可否を判定する仕組み。
- Lambda Event Source Mapping
- SQS / Kinesis / DynamoDB Stream を Lambda のトリガに紐付ける仕組み。