「サーバー間の処理を直接つなげているけれど、片方が落ちたら全部止まる」——オンプレミス環境で、こんな綱渡りの連携に悩まされた経験はないでしょうか。
オンプレミスでは、アプリケーション間のデータ連携にRabbitMQやActiveMQといったメッセージブローカーを自前で構築・運用していました。サーバーの冗長化、ディスク容量の監視、バージョンアップ時のクラスター再構成——メッセージ基盤の維持だけで相当な工数がかかっていたはずです。
この記事では、AWSのフルマネージドメッセージキューサービスであるAmazon SQS(Simple Queue Service)について、オンプレ経験者にもわかりやすく解説します。キューの基本概念から、Standard・FIFOの使い分け、料金体系、実装パターンまで、読み終える頃にはSQSを自信を持って設計に組み込めるようになっているはずです。

なぜメッセージキューが必要なのか(オンプレとの違い)
アプリケーション間の連携方式は、大きく2つに分かれます。「同期通信」と「非同期通信」です。
同期通信は、処理Aが処理Bを直接呼び出し、Bの応答を待ってから次に進む方式です。オンプレ時代のWebサーバーからDBサーバーへのクエリ発行が典型例です。シンプルですが、Bが遅延したりダウンしたりすると、Aも巻き添えになります。
非同期通信では、処理Aはメッセージをキュー(待ち行列)に投入するだけで、すぐに次の処理に移れます。処理Bはキューからメッセージを取り出して、自分のペースで処理します。AとBが直接つながっていないため、片方が一時的にダウンしても全体は止まりません。
・疎結合: 送信側と受信側が互いの存在を意識しない。一方を変更・再起動しても、もう一方に影響しない
・負荷平準化: アクセスが急増しても、キューがバッファとして機能し、受信側は処理能力の範囲で順番に消化できる
・耐障害性: 受信側がダウンしても、メッセージはキューに残る。復旧後に処理を再開できる
オンプレミスでこの仕組みを実現するには、RabbitMQやActiveMQのクラスターを自前で構築し、ディスクの冗長化やフェイルオーバーの設定、監視の仕込みまで全部自分たちでやる必要がありました。Amazon SQSは、このメッセージキュー基盤をAWSが完全に管理してくれるサービスです。インフラの構築・運用は一切不要で、APIを呼ぶだけでメッセージの送受信ができます。
Amazon SQSの基本的な使い方
SQSの操作は非常にシンプルです。やることは3つだけ——キューの作成、メッセージの送信、メッセージの受信と削除です。
1. キューの作成
# AWS CLIでStandardキューを作成 aws sqs create-queue \ --queue-name order-processing-queue \ --region ap-northeast-1 # レスポンス例 # { # "QueueUrl": "https://sqs.ap-northeast-1.amazonaws.com/123456789012/order-processing-queue" # }
キューを作成すると、一意のURL(QueueUrl)が返されます。以後の操作はすべてこのURLを指定して行います。オンプレのRabbitMQでいえば、vhostとキューの作成に相当しますが、ノードの起動やクラスター設定は不要です。
2. メッセージの送信
# メッセージを送信する aws sqs send-message \ --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/order-processing-queue \ --message-body '{"orderId": "A-12345", "item": "Linux入門書", "quantity": 1}'
メッセージの本文(message-body)は最大256KBまでの任意の文字列です。JSON形式で構造化しておくと、受信側でのパースが楽になります。256KBを超えるデータを扱いたい場合は、S3にデータを保存してそのキーだけをメッセージに含める設計が一般的です。
3. メッセージの受信と削除
# メッセージを受信する(最大10件まで一度に取得可能) aws sqs receive-message \ --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/order-processing-queue \ --max-number-of-messages 5 \ --wait-time-seconds 20 # 処理完了後にメッセージを削除する aws sqs delete-message \ --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/order-processing-queue \ --receipt-handle "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a..."
ここがSQSで最も重要なポイントです。メッセージを受信しただけでは、キューから消えません。処理が完了したら、必ずdelete-messageで明示的に削除する必要があります。
なぜこの仕組みなのかというと、受信側が処理途中でクラッシュした場合に備えるためです。削除されなかったメッセージは、一定時間(可視性タイムアウト)が経過すると再びキューに戻り、別のワーカーが再処理できます。オンプレのメッセージブローカーでACK(確認応答)を返す仕組みと同じ考え方です。

StandardキューとFIFOキューの違い
SQSには2種類のキューがあります。用途によって選択を間違えると、設計の根幹に関わるトラブルにつながるので、違いを正確に理解しておいてください。
| 比較項目 | Standardキュー | FIFOキュー |
|---|---|---|
| メッセージ順序 | ベストエフォート(順序保証なし) | 厳密な先入先出順序 |
| 重複配信 | まれに重複する可能性あり | 重複排除あり(5分間) |
| スループット | ほぼ無制限 | バッチ処理で毎秒最大3,000件 |
| キュー名 | 任意の名前 | 末尾に.fifoが必須 |
| 主な用途 | ログ収集、通知配信、バッチ処理 | 注文処理、金融取引、在庫管理 |
Standardキューが向いているケース
順序や重複が問題にならない処理です。たとえば、Webアプリケーションのアクセスログを非同期でElasticsearchに投入する場合、ログの到着順が前後しても実害はありません。スループットに上限がないため、トラフィックの急増にも対応できます。
FIFOキューが向いているケース
「メッセージAの処理が完了してからメッセージBを処理する」という順序保証が必要な場合です。ECサイトの注文処理で、同じ商品への注文が順序通りに処理されないと在庫がマイナスになる——こういった場面ではFIFOキューを選びます。
# FIFOキューの作成 aws sqs create-queue \ --queue-name order-processing-queue.fifo \ --attributes '{ "FifoQueue": "true", "ContentBasedDeduplication": "true" }' \ --region ap-northeast-1 # FIFOキューへのメッセージ送信(MessageGroupIdが必須) aws sqs send-message \ --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/order-processing-queue.fifo \ --message-body '{"orderId": "A-12345", "action": "payment"}' \ --message-group-id "order-A-12345"
FIFOキューでは、MessageGroupIdが順序保証の単位になります。同じMessageGroupIdを持つメッセージは厳密に順序通りに配信されます。異なるMessageGroupIdのメッセージ同士は並列に処理できるため、たとえば注文IDをMessageGroupIdにすれば、注文ごとの順序は保証しつつ、異なる注文は並列処理できます。
料金の仕組み(コスト感覚)
SQSの料金体系はシンプルです。「リクエスト数」に対する従量課金が基本で、キューの存在自体に月額料金はかかりません(2026年4月時点)。
| 料金項目 | Standardキュー | FIFOキュー |
|---|---|---|
| 最初の100万リクエスト/月 | 無料(AWS無料利用枠) | 無料(AWS無料利用枠) |
| 100万リクエスト超過分 | $0.40 / 100万リクエスト | $0.50 / 100万リクエスト |
| データ転送 | 同一リージョン内は無料 | 同一リージョン内は無料 |
※ 東京リージョン(ap-northeast-1)の料金。2026年4月時点。
ここで知っておくべきポイントは、「リクエスト」の数え方です。1回のAPIコールが1リクエストとして課金されます。ただし、receive-messageで一度に複数メッセージを取得しても1リクエストとしてカウントされます。つまり、max-number-of-messagesを10に設定して一括受信するほうが、1件ずつ受信するよりもコスト効率が良いのです。
また、ロングポーリング(wait-time-seconds を1〜20秒に設定)を使えば、空のキューに対するポーリングの回数を大幅に減らせます。ショートポーリング(デフォルト)だとキューが空でも即座にレスポンスが返り、1リクエストとして課金されます。ロングポーリングにするだけで、無駄なリクエストのコストを削減できます。
オンプレミスでRabbitMQを運用していた場合と比較すると、サーバーの月額費用、ストレージ費用、運用人件費がすべてゼロになります。月間数百万件程度のメッセージ処理であれば、SQSの月額は数ドル〜数十ドルに収まるケースがほとんどです。
SQSを組み込む実装パターン
SQSは単独で使うよりも、他のAWSサービスと組み合わせることで真価を発揮します。現場でよく使われる3つのパターンを紹介します。
1. Lambda + SQSトリガー(サーバーレスパターン)
SQSにメッセージが入ると、自動的にLambda関数が起動して処理するパターンです。受信側のワーカーサーバーを自前で用意する必要がなく、メッセージ量に応じてLambdaが自動スケールします。
・構成: APIサーバー → SQS → Lambda → DynamoDB
・用途: 注文の非同期処理、画像のリサイズ処理、メール送信のキューイング
・利点: サーバー管理が完全に不要。メッセージがなければLambdaは起動しないため、コストもゼロに近い
# AWS CLIでLambdaにSQSトリガーを設定する aws lambda create-event-source-mapping \ --function-name order-processor \ --event-source-arn arn:aws:sqs:ap-northeast-1:123456789012:order-processing-queue \ --batch-size 10 \ --maximum-batching-window-in-seconds 5
batch-sizeは一度のLambda実行に渡されるメッセージの最大数です。maximum-batching-window-in-secondsを設定すると、指定した秒数だけメッセージを溜めてからまとめて処理できるため、Lambda実行回数を抑えてコストを最適化できます。
2. EC2ワーカー + SQS(従来型パターン)
オンプレミスからの移行でまず検討すべきパターンです。既存のワーカープロセスをそのままEC2に乗せ、ポーリングでSQSからメッセージを取得して処理します。
・構成: Webサーバー → SQS → EC2ワーカー(Auto Scaling Group)
・用途: 長時間かかる処理(動画エンコード、大量データの集計)
・利点: 既存のアプリケーションコードをほぼそのまま使える
Auto Scaling Groupのスケーリングポリシーに「キューの滞留メッセージ数」を使えば、メッセージが溜まったら自動でワーカーインスタンスを増やし、処理が追いついたら減らす——という運用が可能です。
3. デッドレターキュー(DLQ)パターン
処理に何度も失敗するメッセージを別のキュー(デッドレターキュー)に自動退避させるパターンです。毒メッセージ(poison message)が延々と再処理されてワーカーのリソースを浪費する問題を防ぎます。
# デッドレターキューを作成 aws sqs create-queue --queue-name order-processing-dlq # メインキューのRedrivePolicy(再処理ポリシー)を設定 # maxReceiveCount=3 → 3回受信されても削除されないメッセージをDLQに移動 aws sqs set-queue-attributes \ --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/order-processing-queue \ --attributes '{ "RedrivePolicy": "{\"deadLetterTargetArn\":\"arn:aws:sqs:ap-northeast-1:123456789012:order-processing-dlq\",\"maxReceiveCount\":\"3\"}" }'
DLQに溜まったメッセージは、CloudWatchアラートで監視します。DLQにメッセージが入ったら通知を飛ばし、原因を調査して修正した後、DLQのメッセージをメインキューに再投入(redrive)する運用が一般的です。
よくあるトラブルと対処法
【トラブル1】メッセージが消えない(可視性タイムアウトの設定ミス)
受信したメッセージの処理に10分かかるのに、可視性タイムアウトが30秒(デフォルト)のまま——という設定ミスが現場で最も多いトラブルです。30秒経過するとメッセージがキューに戻り、別のワーカーが同じメッセージを受信して二重処理が発生します。
対処: 可視性タイムアウトは「処理にかかる最大時間 + 余裕(30秒〜1分程度)」に設定します。処理時間が読めない場合は、ChangeMessageVisibility APIで処理中にタイムアウトを延長する方法もあります。
# 可視性タイムアウトを10分(600秒)に設定 aws sqs set-queue-attributes \ --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/order-processing-queue \ --attributes '{"VisibilityTimeout": "600"}'
【トラブル2】Standardキューでメッセージが重複して処理される
Standardキューは「少なくとも1回配信(at-least-once delivery)」を保証しています。つまり、まれにメッセージが重複配信される可能性があります。
対処: 受信側の処理を冪等(べきとう)にする設計が基本です。メッセージにユニークIDを含めておき、処理済みIDをDynamoDBやRDSに記録して、重複チェックを行います。順序と重複の両方を厳密に管理したい場合は、FIFOキューを使ってください。
【トラブル3】ロングポーリングを使っていないのにメッセージが取れない
ショートポーリング(wait-time-seconds=0)では、SQSの分散ノードの一部だけにリクエストが届くため、キューにメッセージがあっても空のレスポンスが返ることがあります。
対処: wait-time-secondsを1〜20に設定してロングポーリングを有効にします。すべてのノードを確認してからレスポンスを返すため、メッセージの取りこぼしがなくなり、無駄なリクエスト(空振り)も減ります。推奨値は20秒です。
【トラブル4】DLQにメッセージが溜まり続ける
DLQはエラーメッセージの退避先であって、ゴミ箱ではありません。DLQにメッセージが溜まっている場合、処理ロジックにバグがあるか、メッセージのフォーマットが想定と異なっている可能性があります。
対処: DLQのメッセージ数をCloudWatchメトリクス(ApproximateNumberOfMessagesVisible)で監視し、閾値を超えたらSNSで通知する仕組みを入れます。原因を修正したら、SQSコンソールの「Start DLQ redrive」機能で元のキューにメッセージを戻して再処理できます。

本記事のまとめ
Amazon SQSは、アプリケーション間の連携を疎結合にし、システム全体の耐障害性とスケーラビリティを向上させるための基盤サービスです。
| やりたいこと | SQSでの実現方法 | オンプレ相当 |
|---|---|---|
| メッセージの非同期送受信 | Standardキュー | RabbitMQ / ActiveMQ |
| 順序保証付きメッセージ処理 | FIFOキュー | RabbitMQ(single consumer) |
| 処理失敗メッセージの退避 | デッドレターキュー(DLQ) | エラーキュー(自前実装) |
| サーバーレス連携 | Lambda + SQSトリガー | 該当なし |
| ワーカーの自動スケール | Auto Scaling + キュー深度 | 手動でワーカー増減 |
オンプレミスでメッセージブローカーを運用していた方にとって、SQSはインフラ管理から解放される大きな一歩になります。まずはStandardキューを作成して、既存の同期処理の一部を非同期に置き換えるところから始めてみてください。メッセージが100万件/月以内なら無料枠に収まるため、コストを気にせず試せます。キュー設計のコツは「どこを切り離せばシステムが強くなるか」を考えること——その視点は、オンプレで培ったインフラ経験がそのまま活きるはずです。
クラウド上のLinuxサーバー構築やEC2の操作については、姉妹サイトLinuxMaster.JPで詳しく解説しています。
サーバー間の連携、直結のまま運用していませんか?
SQSをはじめとするAWSサービスの実践的な設計パターンを、毎週お届けしています。
オンプレの経験を活かしながら、現場で使えるクラウドスキルを体系的に身につけたい方へ、メルマガで実践的なクラウド活用ノウハウをお届けしています。


コメント