コンテンツにスキップ

Amazon SQS 入門

Amazon Simple Queue Service(SQS)は、AWS が提供するフルマネージドのメッセージキューサービスです。 アプリケーション同士を疎結合にし、負荷の平準化や非同期処理の基盤として広く使われます。

この記事では、SQS を初めて触るときに押さえておきたい概念と、設計・運用でつまずきやすいポイントを整理します。

SQS は「メッセージを一時的に預かり、別のコンポーネントが取り出す」ためのキューです。 送信側(プロデューサー)と受信側(コンシューマー)を直接つながずに処理を分離できます。

flowchart LR
    P[プロデューサー] -->|SendMessage| Q[(SQS キュー)]
    Q -->|ReceiveMessage| C1[コンシューマー A]
    Q -->|ReceiveMessage| C2[コンシューマー B]

典型的な用途は次のとおりです。

用途説明
非同期処理API が即座に応答し、重い処理をワーカーに任せる
負荷の平準化スパイク時にメッセージをキューに溜め、処理能力に合わせて消化する
疎結合送信側・受信側のデプロイや障害を独立させる
リトライの分離失敗した処理を DLQ に逃がし、本流を止めない
用語意味
キュー(Queue)メッセージを格納する論理的な入れ物
メッセージ(Message)本文(最大 256 KiB)と属性・メタデータの組
プロデューサーSendMessage などでメッセージを送る側
コンシューマーReceiveMessage で取り出し、処理後に DeleteMessage する側
可視性タイムアウト受信後に他コンシューマーから見えなくなる時間
DLQ(Dead-Letter Queue)何度も処理に失敗したメッセージを退避するキュー

SQS には大きく StandardFIFO の2種類があります。用途に応じて選びます。

項目Standard キューFIFO キュー
スループットほぼ無制限(高スループット向け)300 TPS(バッチ利用で拡張可能)
配信順序ベストエフォート(順不同のことがある)送信順を保証
重複少なくとも1回(重複の可能性あり)重複排除(同一メッセージの再送を抑制)
キュー名任意末尾が .fifo 必須
料金リクエスト課金Standard よりやや高め
向いている例ログ集約、通知、汎用ジョブ注文処理、在庫引当など順序が重要な処理

選び方の目安

  • 順序や重複が厳密でなく、スループットを優先する → Standard
  • 「同じ注文を二重に処理してはいけない」「処理順を守りたい」 → FIFO

FIFO では MessageGroupId(同一グループ内で順序保証)と MessageDeduplicationId(重複排除)の指定が重要です。

コンシューマーがメッセージを受け取ってから削除するまでの流れを理解しておくと、二重処理やメッセージ消失の原因を切り分けやすくなります。

sequenceDiagram
    participant P as プロデューサー
    participant Q as SQS
    participant C as コンシューマー

    P->>Q: SendMessage
    Q->>C: ReceiveMessage
    Note over Q,C: 可視性タイムアウト中は他から見えない
    C->>C: ビジネス処理
    alt 成功
        C->>Q: DeleteMessage
    else タイムアウト前に Delete しない
        Q->>C: 再配信(別ワーカーにも届く可能性)
    end
  1. 送信: プロデューサーがキューにメッセージを投入する
  2. 受信: コンシューマーが ReceiveMessage で取得する(この時点ではキューからは消えない)
  3. 処理中: 可視性タイムアウトの間、同じメッセージは他の受信者には見えない
  4. 削除: 処理が成功したら DeleteMessageReceiptHandle 必須)でキューから除去する
  5. 再配信: 削除されずに可視性タイムアウトを過ぎると、再度配信対象になる

デフォルトは 30 秒です。処理にかかる時間より十分長く設定し、処理中に同じメッセージが別ワーカーに渡らないようにします。

長い処理では ChangeMessageVisibility で延長できます。逆に、処理が明らかに失敗したときは 0 に戻して早く再試行させることもあります。

少なくとも1回配信(at-least-once)

Section titled “少なくとも1回配信(at-least-once)”

SQS は 少なくとも1回 配信を保証します。つまり、同じメッセージが複数回届く可能性があります。 コンシューマー側は 冪等性(同じメッセージを何度処理しても結果が壊れない)を前提に実装するのが定石です。

ロングポーリングとショートポーリング

Section titled “ロングポーリングとショートポーリング”

ReceiveMessage では WaitTimeSeconds で待ち方を制御します。

方式WaitTimeSeconds特徴
ショートポーリング0即座に返る。空キューだと無駄な API 呼び出しが増えやすい
ロングポーリング1〜20メッセージが来るまで待機。空ポーリングを減らしコスト・負荷を抑えられる

新規キューでは ReceiveMessageWaitTimeSeconds(キュー属性)を 20 にしておく運用が一般的です。

同じメッセージが何度も処理に失敗すると、本キューで無限に再配信が続きます。 DLQ に退避させ、本流のコンシューマーを守ります。

flowchart LR
    M[メッセージ] --> Q[本キュー]
    Q -->|処理失敗が閾値超え| DLQ[DLQ]
    DLQ --> O[運用・調査・再投入]

設定の要点:

  • 本キューに Redrive policy を設定し、DLQ の ARN を指定する
  • maxReceiveCount(何回受信したら DLQ に送るか)を決める(例: 3〜5)
  • DLQ のメッセージはアラート対象にし、原因調査後に手動またはスクリプトで再投入する

DLQ は「ゴミ箱」ではなく 障害の観測点 として扱うのがおすすめです。

代表的なアーキテクチャパターン

Section titled “代表的なアーキテクチャパターン”

複数の EC2 / Lambda / ECS タスクが同じキューをポーリングし、並列に処理します。 Standard キューでは複数ワーカーにメッセージが分散されます。

1つのイベントを SNS トピックに publish し、複数の SQS キューに配信してサブシステムごとに処理させるパターンです。 通知・監査・非同期ジョブの分岐に向いています。

SQS をイベントソースに Lambda を起動できます。 バッチサイズや ReportBatchItemFailures(部分失敗の報告)を使うと、失敗したメッセージだけ再試行できます。

設計・運用のベストプラクティス

Section titled “設計・運用のベストプラクティス”
  • 本文に巨大なペイロードを載せず、S3 のオブジェクトキーや ID だけを送る(キューは軽く、実データは別ストア
  • スキーマのバージョンや correlationId を属性に載せ、トレースしやすくする
  • 可視性タイムアウト > 処理の p99 時間 を目安にする
  • 指数バックオフはコンシューマー側の再試行設計とセットで考える(SQS 自体は再配信間隔を細かく制御しない)
  • キューポリシーと IAM で最小権限(sqs:SendMessage / ReceiveMessage / DeleteMessage を役割ごとに分離)
  • 機密データは本文に平文で載せない。必要なら KMS で暗号化(SSE-SQS / SSE-KMS)

CloudWatch メトリクスで次を監視します。

メトリクス見る意味
ApproximateNumberOfMessagesVisible滞留(バックログ)の増加
ApproximateAgeOfOldestMessage最古メッセージの待ち時間(SLA 違反の兆候)
NumberOfMessagesDeleted正常消化の量
DLQ の ApproximateNumberOfMessagesVisible処理失敗の発生
勘違い実際
Receive したらメッセージは消えるDeleteMessage するまでキューに残る
SQS は exactly-once少なくとも1回。冪等性はアプリ側の責務
DLQ に入ったら自動で復旧する人手または別ジョブで調査・再投入が必要
FIFO なら Standard より常に正しいFIFO はスループットと設定(GroupId など)の制約がある

キュー作成と送受信の流れです(リージョン・プロファイルは環境に合わせてください)。

Terminal window
# キュー作成
aws sqs create-queue --queue-name my-app-jobs
# URL を取得(例)
QUEUE_URL="https://sqs.ap-northeast-1.amazonaws.com/123456789012/my-app-jobs"
# 送信
aws sqs send-message \
--queue-url "$QUEUE_URL" \
--message-body '{"jobId":"job-001","action":"resize-image"}'
# 受信(ロングポーリング 20 秒)
aws sqs receive-message \
--queue-url "$QUEUE_URL" \
--wait-time-seconds 20 \
--visibility-timeout 60
# 処理成功後、ReceiptHandle を使って削除
aws sqs delete-message \
--queue-url "$QUEUE_URL" \
--receipt-handle "<ReceiptHandle from receive-message>"

本番では AWS SDK(例: AWS SDK for JavaScript v3 の @aws-sdk/client-sqs)や IaC(CloudFormation / Terraform / CDK)でキューと DLQ、IAM、監視アラームをまとめて定義するのが一般的です。

  • SQS は 疎結合・非同期・負荷平準化 のためのマネージドキュー
  • Standard は高スループット、FIFO は順序と重複排除が必要なとき
  • 受信後は DeleteMessage までが1サイクル。処理時間と 可視性タイムアウト の整合が重要
  • 少なくとも1回 配信を前提に 冪等 に実装する
  • 失敗の観測と本流保護のために DLQ とメトリクス監視をセットで用意する

関連サービスとして、イベント配信には Amazon SNS、スケジュール実行には EventBridge、大規模ストリーミングには Kinesis なども選択肢になります。要件(順序、スループット、保持期間、再実行モデル)に応じて使い分けてください。