【AWSサービス 基礎編】Amazon SQS でキューを作り、SNS との違いを体験する

目次

概要

Amazon Simple Queue Service(Amazon SQS)は、AWS が提供するフルマネージドのメッセージキューサービスです。分散されたシステムやコンポーネントの間にキューを置き、送り手と受け手を切り離して(疎結合にして)連携させるために使います。

例えば、注文を受け付ける Web アプリと、在庫引き当てや発送処理を行うバックエンドを直接つなぐと、バックエンドが止まったり処理が詰まったりしたときに注文の受け付けまで巻き込まれます。間に SQS のキューを置けば、Web アプリはキューにメッセージを入れるだけで済み、バックエンドは自分のペースでキューから取り出して処理できます。

SQS とよく並べて語られるのが、パブリッシュ/サブスクライブ型の Amazon SNS です。どちらも「メッセージを受け渡すサービス」ですが、受け手への届け方が異なり、組み合わせて使うことも多いサービスです。この記事では、標準キューの作成からメッセージの送受信、可視性タイムアウトとデッドレターキューの動き、そして SNS トピックから複数のキューへ同時に配信するファンアウト構成までを、AWS マネジメントコンソールで体験します。

クラウドおさる

猿山でも、バナナの注文を受ける猿と運ぶ猿が直接やりとりすると、運び手が昼寝した途端に注文が止まってしまうのでござる。間に「注文箱」を置くと何が変わるのか、SQS で確かめるでござる!

キューで送り手と受け手を切り離し、SNS と組むと 1 回の発行を複数のキューに配れる
キューで送り手と受け手を切り離し、SNS と組むと 1 回の発行を複数のキューに配れる

この記事のメリット

  • 疎結合の考え方と、メッセージキューが果たす役割を理解できる
  • 標準キューと FIFO キューの違いを把握できる
  • 可視性タイムアウト、メッセージ保持期間、ロングポーリング、デッドレターキューといった SQS の基本設定の意味が分かる
  • SNS(プッシュ型・1 対多)と SQS(プル型・キューで受け止める)の違いと、両者を組み合わせたファンアウト構成を理解できる
  • コンソールでメッセージを送受信し、可視性タイムアウトとデッドレターキューの挙動を実際に確認できる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。

クラウドおさる

基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

疎結合とメッセージキュー

クラウドおさる

とひさん、SQS は「キュー」のサービスと聞いたでござるが、キューとは何でござるか?

土肥

キューは「順番待ちの列」のことだよ。SQS では、メッセージを送る側(プロデューサー)がキューにメッセージを入れて、受け取る側(コンシューマー)がキューからメッセージを取り出して処理するんだ。送る側と受け取る側が直接つながらないのがポイントだね。

クラウドおさる

直接つながらないと、何がうれしいのでござる?

土肥

例えば受け取る側が一時的に止まっていても、メッセージはキューに残っているから失われないんだ。送る側は相手の状態を気にせずキューに入れ続けられるし、受け取る側は処理できるペースで取り出せばいい。こうやってお互いの都合に引きずられない作りを「疎結合」って言うんだよ。SQS は、分散されたシステムやコンポーネントを統合しつつ切り離すための、耐久性のあるホスト型キューを提供してくれるサービスなんだ。

クラウドおさる

なるほど、猿山の「注文箱」と同じでござるな! 注文する猿は箱に紙を入れるだけ、運ぶ猿は手が空いたら箱から取ればよいのでござる。

土肥

まさにそれ! ちなみに受け取る側は EC2 上のアプリでもいいし、Lambda 関数でもいいよ。Lambda の場合は Lambda がキューをポーリングして、メッセージのバッチを渡して関数を呼び出してくれるんだ。Lambda そのものについては「AWS Lambda で関数を作成しイベント駆動で実行する」で紹介しているよ。

クラウドおさる

キューに入ったメッセージは、どういう順番で処理されていくのでござるか?

土肥

基本の流れはこうだよ。

段階誰が何をするか
送信プロデューサーキューにメッセージを送る
受信コンシューマーキューをポーリングしてメッセージを受け取る。受け取ったメッセージはキューに残ったまま、一定時間ほかのコンシューマーから見えなくなる
削除コンシューマー処理が終わったら、メッセージを明示的に削除する
土肥

大事なのは、「受信しただけではキューから消えない」ってことだね。処理が終わったらコンシューマーが自分で削除するんだ。

受信しただけでは消えない。処理が終わったら削除し、それまでは可視性タイムアウトで隠れる
受信しただけでは消えない。処理が終わったら削除し、それまでは可視性タイムアウトで隠れる

標準キューと FIFO キュー

クラウドおさる

キューにも種類があるのでござるか?

土肥

うん、「標準キュー」と「FIFO キュー」の 2 種類があるよ。違いをまとめるとこんな感じだね。

項目標準キューFIFO キュー
配信少なくとも 1 回(At-least-once)。まれに同じメッセージが複数回届くことがある1 回のみ処理(重複排除の仕組みがある)
順序ベストエフォート(送った順に届くとは限らない)送信順(先入れ先出し)が保たれる
スループットほぼ無制限API 呼び出しは 1 秒あたり最大 300。10 件ずつのバッチなら 1 秒あたり最大 3,000 メッセージ。高スループットモードではさらに引き上げられる
向いている用途大量のメッセージを高速にさばきたい処理処理の順番が大事な処理(コマンドの実行順、価格変更の反映など)
クラウドおさる

標準キューは同じメッセージが 2 回届くこともあるのでござるか……。それでは困らないのでござる?

土肥

いいところに気づいたね! 標準キューを使うときは、同じメッセージを 2 回処理しても結果が変わらないように(べき等に)アプリを作っておくのが前提なんだ。順番と 1 回きりの処理がどうしても必要なら FIFO キューを選ぶ、という使い分けだよ。

クラウドおさる

猿山のバナナ配給で言えば、同じ注文票が 2 枚届いても「もう配ったでござる」と台帳で確かめる仕組みを先に作っておく、ということでござるな!

可視性タイムアウトとメッセージ保持期間

クラウドおさる

さっきの「受け取ったメッセージが一定時間ほかから見えなくなる」というのは、どういう仕組みでござるか?

土肥

それが「可視性タイムアウト」だよ。コンシューマーがメッセージを受信すると、そのメッセージはキューに残ったまま、可視性タイムアウトの間はほかのコンシューマーから見えなくなるんだ。これで、1 つのメッセージを複数のコンシューマーが同時に処理してしまうのを防いでいるんだね。既定値は 30 秒で、0 秒から 12 時間まで設定できるよ。

クラウドおさる

もし処理の途中でコンシューマーが倒れて、削除されないままだったらどうなるのでござる?

土肥

可視性タイムアウトが切れると、メッセージはまたキューに見えるようになって、別のコンシューマーが受け取れるようになるよ。だから処理に失敗してもメッセージは失われないんだ。逆に、可視性タイムアウトを長くしすぎると、失敗したメッセージが再び見えるまで時間がかかって、再試行が遅れることもあるから注意してね。

クラウドおさる

キューに入れたメッセージは、ずっと残しておけるのでござるか?

土肥

「メッセージ保持期間」が過ぎると削除されるよ。既定値は 4 日で、1 分から 14 日まで設定できるんだ。キューの主な設定をまとめておくね。

設定項目意味既定値設定できる範囲
可視性タイムアウト受信したメッセージがほかのコンシューマーから見えない時間30 秒0 秒〜12 時間
メッセージの保持期間キューに残っているメッセージを保持する時間4 日1 分〜14 日
配信の遅延キューに追加されたメッセージを配信するまで遅らせる時間0 秒0 秒〜15 分
メッセージの受信待ち時間受信リクエストを受けてから、メッセージが届くのを待つ最大時間0 秒(ショートポーリング)0〜20 秒
クラウドおさる

受け取った猿が「いま運んでいるでござる」と札を掛けておく時間が可視性タイムアウト、注文箱に紙を置いておける期限が保持期間でござるな。札の期限が切れたら、別の猿が運び直せるのでござる。

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

クラウドおさる

表にあった「メッセージの受信待ち時間」が気になるでござる。

土肥

SQS はコンシューマーが自分から取りに行く「プル型」なんだ。取りに行くことをポーリングって言うよ。ポーリングには 2 種類あって、待ち時間が 0 秒の「ショートポーリング」は、メッセージがなくてもすぐ空の応答を返すんだ。一部のサーバーだけを調べるから、メッセージがあるのに空が返る(偽の空応答)こともあるよ。

クラウドおさる

空の応答ばかり返ってきたら、何度も取りに行くことになりそうでござる……。

土肥

そうなんだ。そこで待ち時間を 0 より大きくする「ロングポーリング」を使うと、すべてのサーバーを調べたうえで、メッセージが届くまで最大 20 秒待ってから応答してくれる。空の応答や偽の空応答が減るから、リクエスト回数が減ってコストを抑えられる可能性があるんだよ。

クラウドおさる

箱をのぞいて空ならすぐ帰るのがショート、しばらく箱の前で待ってみるのがロングでござるな。何度も山を往復しなくて済むのでござる!

デッドレターキュー

クラウドおさる

何度受け取っても処理に失敗するメッセージがあったら、ずっとキューの中をぐるぐる回ってしまうのでござるか?

土肥

そこで使うのが「デッドレターキュー(DLQ)」だよ。ソースキューにリドライブポリシーを設定しておくと、コンシューマーが受信した回数が「最大受信数(maxReceiveCount)」を超えたメッセージを、デッドレターキューに移してくれるんだ。最大受信数は 1〜1,000 の範囲で設定できるよ。

クラウドおさる

移したメッセージはどうするのでござる?

土肥

失敗したメッセージを分けておけば、中身を見て原因を調べられるよね。DLQ にはいくつか決まりがあるから押さえておこう。

  • デッドレターキューは、ソースキューと同じ AWS アカウント・同じリージョンにある必要がある
  • 標準キューのデッドレターキューは標準キュー、FIFO キューのデッドレターキューは FIFO キューにする
  • 標準キューの場合、メッセージの有効期限は元のキューに入った時刻のまま引き継がれる。そのため、デッドレターキューの保持期間はソースキューより長くしておくのがベストプラクティス
クラウドおさる

何度運んでも受け取ってもらえない注文票は、長老会の「要確認箱」に回して、あとで原因を調べるのでござるな!

SNS と SQS の違いとファンアウト

クラウドおさる

SNS もメッセージを届けるサービスでござったな。SQS とはどう違うのでござる?

土肥

SNS はパブリッシャーがトピックに発行したメッセージを、サブスクライブしている複数の受け手へ SNS 側から配信するサービスだったよね(詳しくは「Amazon SNS でトピックを作成しメッセージを配信する」で紹介しているよ)。SQS はキューにメッセージを溜めておいて、コンシューマーが取りに来るのを待つんだ。

観点Amazon SNSAmazon SQS
届け方トピックからサブスクライバーへ配信する(プッシュ型)コンシューマーがキューをポーリングして取りに行く(プル型)
受け手の数1 つのメッセージを複数のサブスクライバーへ(1 対多)1 つのメッセージは 1 つのコンシューマーが処理する(1 対 1)
メッセージの保管キューを持たないキューに保持期間のあいだ保管する
向いている用途複数の受け手への即時通知順序や取りこぼし防止が大事な処理
クラウドおさる

両方のいいところを合わせることはできないのでござるか?

土肥

できるよ! それが「ファンアウト」構成なんだ。SNS トピックに複数の SQS キューをサブスクライブしておくと、トピックに 1 回発行するだけで、すべてのキューに同じメッセージが届く。各キューの先では、発送担当や請求担当のようなそれぞれのコンシューマーが、自分のペースで処理できるんだね。

クラウドおさる

SNS がキューにメッセージを入れるには、何か許可が要るのではござらぬか?

土肥

鋭いね! キューのアクセスポリシーで、sns.amazonaws.com に sqs:SendMessage を許可する必要があるよ。そのとき aws:SourceArn 条件でトピックの ARN を指定しておくと、ほかのトピックから勝手に送られるのを防げるんだ。それから、キューを AWS マネージドキー(aws/sqs)の KMS 暗号化にしていると SNS から送れないから、KMS で暗号化したいときはカスタマーマネージドキーを使ってキーポリシーに SNS を許可する必要があるよ。

クラウドおさる

一度の掛け声で、発送係と請求係それぞれの注文箱に同じ紙が入るのでござるな。箱の入口に「この掛け声からなら受け取る」と札を貼っておくのがアクセスポリシーでござる!

1 回の発行が、発送用と請求用の 2 つのキューに届く(ファンアウト)
1 回の発行が、発送用と請求用の 2 つのキューに届く(ファンアウト)
新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

実践

ハンズオンガイド12 ステップ画面 11 枚

コンソールの横に開いて、チェックしながら進めましょう。

ガイドを開く

別タブで開きます。チェックはこのブラウザに保存されます。

ここでは、標準キューを作成してメッセージを送受信し、可視性タイムアウトとデッドレターキューの動きを確認します。最後に SNS トピックから 2 つのキューへのファンアウトを確認します。

前提条件

  • リージョン: ap-northeast-1(東京)
  • AWS マネジメントコンソールにログイン済みで、Amazon SQS と Amazon SNS を操作できる IAM 権限があること
  • 事前に作成しておくリソースはありません

作成するリソース一覧

リソース種別リソース名用途
SQS 標準キューhandson-orders-queue送受信・可視性タイムアウトの確認用(ソースキュー)
SQS 標準キューhandson-orders-dlqhandson-orders-queue のデッドレターキュー
SNS スタンダードトピックhandson-order-eventsファンアウトの発行元
SQS 標準キューhandson-shipping-queueファンアウトの受け手(発送用)
SQS 標準キューhandson-billing-queueファンアウトの受け手(請求用)

標準キューを作成する

  • AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します
  • 上部の検索バーに SQS と入力し、表示された「Simple Queue Service」を選択します
  • 「キューを作成」をクリックします
  • 「詳細」で以下を設定します
  • タイプ: 標準(デフォルト)
  • 名前: handson-orders-queue
  • 「設定」で以下を設定します
  • 可視性タイムアウト: 1 と入力し、右隣の単位を「分」にします(後の手順で「見えない時間」を確かめやすくするため、既定の 30 秒から延ばします)
  • その他の項目(メッセージ保持期間 4 日、配信遅延 0 秒、メッセージ受信待機時間 0 秒 など)はデフォルトのままにします
  • 「暗号化」「アクセスポリシー」「デッドレターキュー」などその他の項目はデフォルトのままにします(暗号化は、既定で Amazon SQS キー(SSE-SQS)によるサーバー側の暗号化が有効になっています。このままで、後の手順で SNS から届くメッセージも受け取れます)
  • ページ下部の「キューを作成」をクリックします
handson-orders-queue の作成画面(タイプ「標準」、名前、可視性タイムアウト 1 分を設定した状態)
handson-orders-queue の作成画面(タイプ「標準」、名前、可視性タイムアウト 1 分を設定した状態)

キューの詳細画面が表示され、「詳細」に URL と ARN が表示されていることを確認します。

メッセージを送信・受信・削除する

  • キューの詳細画面の右上で「メッセージを送受信」をクリックします
  • 「メッセージを送信」で、メッセージ本文に order-001: banana x 3 と入力します
  • 「メッセージを送信」をクリックします
  • 「メッセージを送信」セクションの上部に、「メッセージは送信済みであり、受信可能です。」と表示されます
「メッセージを送受信」画面でメッセージ本文を入力した状態
「メッセージを送受信」画面でメッセージ本文を入力した状態
  • 同じ画面の下部「メッセージを受信」で「メッセージをポーリング」をクリックします(「ポーリング期間」の既定値は 30 秒で、進行状況バーが 100% になるまでポーリングが続きます)
  • 「メッセージ」の一覧に、送信したメッセージ(ID と受信数 1)が表示されます
  • メッセージが表示されたら「ポーリングを停止」をクリックします。コンソールは、ポーリングを止める(または期間が終わる)と受信したメッセージを再び受信できる状態に戻します
  • メッセージ ID をクリックすると、「本文」タブで order-001: banana x 3 が確認できます。確認できたら「完了」をクリックして閉じます
「メッセージをポーリング」の結果(受信したメッセージの ID と受信数が表示されている状態)
「メッセージをポーリング」の結果(受信したメッセージの ID と受信数が表示されている状態)
  • 一覧で受信したメッセージのチェックボックスを選択し、一覧の右上の「削除」をクリックします
  • 「メッセージ を削除」ダイアログで「削除」をクリックします

メッセージは受信しただけではキューから消えず、コンシューマーが削除して初めて消えることが確認できます。

可視性タイムアウト中は見えないことを確認する

コンソールは、ポーリングを止める(または期間が終わる)と受信したメッセージを再び受信できる状態に戻します。そのため、「ポーリングを終えてから、すぐにもう一度ポーリングする」やり方では、可視性タイムアウトの動きを確かめられません。ここでは、ポーリング期間を可視性タイムアウトより長い 90 秒にして、1 回のポーリングの途中で受信数がどう変わるかを見ます。

  • 「メッセージを受信」の「ポーリング設定を編集」をクリックします
  • 「ポーリング期間」を 90(秒)に変更し、「保存」をクリックします(この設定はブラウザに保持され、画面を開き直しても残ります)
  • 「メッセージを送信」で、メッセージ本文に order-002: banana x 5 と入力し、「メッセージを送信」をクリックします
  • 「メッセージをポーリング」をクリックし、order-002 のメッセージが受信数 1 で表示されることを確認します(今回は「ポーリングを停止」も削除もせず、そのまま待ちます)
  • ポーリングを開始してから 30 秒ほどたった時点でも、受信数が 1 のままであること、「利用可能なメッセージ」が 0 であることを確認します。可視性タイムアウト(1 分)の間は、ポーリングを続けていても同じメッセージが再び届きません
ポーリング開始から 30 秒ほどたった状態(受信数が 1 のまま、可視性タイムアウト中)
ポーリング開始から 30 秒ほどたった状態(受信数が 1 のまま、可視性タイムアウト中)
  • さらに待ち、ポーリングを開始してから 1 分を少し過ぎたころに、order-002 の受信数が 2 に増えることを確認します
  • 確認できたら「ポーリングを停止」をクリックし、order-002 を選択して「削除」します
可視性タイムアウト経過後に同じメッセージが受信数 2 で再表示された状態
可視性タイムアウト経過後に同じメッセージが受信数 2 で再表示された状態
クラウドおさる

削除しないまま 1 分たつと、同じ注文票がまた箱に戻ってきたでござる。受け取っただけでは「運び終わった」ことにならず、削除して初めて完了なのでござるな。

デッドレターキューを設定する

まず、デッドレターキューにする標準キューを作成します。

  • 左側ナビゲーションの「キュー」を選択し、「キューを作成」をクリックします
  • 以下を設定します
  • タイプ: 標準
  • 名前: handson-orders-dlq
  • メッセージ保持期間: 14 日(ソースキューの 4 日より長くします)
  • その他の項目はデフォルトのままにし、「キューを作成」をクリックします

次に、ソースキューにデッドレターキューを設定します。

  • 左側ナビゲーションの「キュー」から handson-orders-queue を選択し、右上の「編集」をクリックします
  • 「デッドレターキュー」セクションで「有効」を選択します
  • 以下を設定します
  • キューの選択: 「キュー ARN」のドロップダウンから handson-orders-dlq の ARN を選択
  • 最大受信数: 2(既定値は 10)
  • ページ下部の「保存」をクリックします
handson-orders-queue の編集画面のデッドレターキュー設定(有効、handson-orders-dlq、最大受信数 2)
handson-orders-queue の編集画面のデッドレターキュー設定(有効、handson-orders-dlq、最大受信数 2)

最大受信数を超えたメッセージが移ることを確認する

  • handson-orders-queue の詳細画面で「メッセージを送受信」をクリックします
  • メッセージ本文に order-003: broken order と入力し、「メッセージを送信」をクリックします
  • 「メッセージをポーリング」をクリックし、order-003 が受信数 1 で表示されることを確認したら、「ポーリングを停止」をクリックします(削除しません)
  • もう一度「メッセージをポーリング」をクリックし、受信数 2 で表示されることを確認したら、「ポーリングを停止」をクリックします(削除しません。コンソールはポーリングを止めると受信したメッセージを戻すので、1 分待つ必要はありません)
  • 3 回目として「メッセージをポーリング」をクリックし、order-003 が表示されないことを確認します(受信数が最大受信数 2 を超えるため、デッドレターキューに移されます)。確認できたら「ポーリングを停止」をクリックします

続いて、デッドレターキュー側を確認します。

  • 左側ナビゲーションの「キュー」を選択し、handson-orders-dlq の「利用可能なメッセージ」が 1 になっていることを確認します(件数の反映に少し時間がかかるときは、一覧の更新アイコンをクリックします)
  • handson-orders-dlq を選択して「メッセージを送受信」をクリックし、「メッセージをポーリング」をクリックします
  • 受信したメッセージの ID をクリックし、「本文」タブで order-003: broken order が確認できることを確認します(受信数は、元のキューでの 2 回にデッドレターキューでの 1 回を加えた 3 と表示されます)
handson-orders-dlq で受信したメッセージの本文(order-003: broken order)を開いた状態
handson-orders-dlq で受信したメッセージの本文(order-003: broken order)を開いた状態

SNS ファンアウト用のキューを 2 つ作成する

  • 左側ナビゲーションの「キュー」を選択し、「キューを作成」をクリックします
  • タイプ: 標準、名前: handson-shipping-queue を設定し、その他の項目はデフォルトのまま「キューを作成」をクリックします
  • 同じ手順で、名前 handson-billing-queue の標準キューを作成します
  • 作成した 2 つのキューの詳細画面で、それぞれの ARN(arn:aws:sqs:ap-northeast-1:<アカウントID>:handson-shipping-queue の形式)を控えておきます

SNS トピックを作成する

  • 上部の検索バーに SNS と入力し、表示された「Simple Notification Service」を選択します
  • 左側ナビゲーションの「トピック」を選択し、「トピックの作成」をクリックします
  • 以下を設定します
  • タイプ: スタンダード(既定では「FIFO」が選ばれているので、「スタンダード」に切り替えます)
  • 名前: handson-order-events
  • その他の項目はデフォルトのままにし、「トピックの作成」をクリックします
  • トピックの詳細画面に表示される ARN(arn:aws:sns:ap-northeast-1:<アカウントID>:handson-order-events の形式)を控えておきます

キューのアクセスポリシーで SNS からの送信を許可する

SNS トピックがキューにメッセージを送れるよう、2 つのキューのアクセスポリシーを編集します。

  • SQS コンソールに戻り、左側ナビゲーションの「キュー」から handson-shipping-queue を選択します
  • キューの詳細画面の「キューポリシー」タブ(既定で選ばれています)にある「アクセスポリシー」の「編集」をクリックします(画面右上の「編集」からも、同じ編集画面に進めます)
  • 編集画面の「アクセスポリシー」セクションの JSON エディタで、既存のステートメント(キューの所有者を許可するもの)は残したまま、"Statement" の配列に以下のステートメントを追加します。<アカウントID> は自分のアカウント ID に置き換えます
{
  "Sid": "AllowSNSOrderEvents",
  "Effect": "Allow",
  "Principal": {
    "Service": "sns.amazonaws.com"
  },
  "Action": "sqs:SendMessage",
  "Resource": "arn:aws:sqs:ap-northeast-1:<アカウントID>:handson-shipping-queue",
  "Condition": {
    "ArnEquals": {
      "aws:SourceArn": "arn:aws:sns:ap-northeast-1:<アカウントID>:handson-order-events"
    }
  }
}
  • ページ下部の「保存」をクリックします
handson-shipping-queue のアクセスポリシー編集画面(SNS からの sqs:SendMessage を許可するステートメントを追加した状態)
handson-shipping-queue のアクセスポリシー編集画面(SNS からの sqs:SendMessage を許可するステートメントを追加した状態)
  • handson-billing-queue についても同じ手順で編集します。Resource は arn:aws:sqs:ap-northeast-1:<アカウントID>:handson-billing-queue に置き換えます

2 つのキューをトピックにサブスクライブする

  • SNS コンソールの左側ナビゲーションで「トピック」を選択し、handson-order-events をクリックします
  • 「サブスクリプション」タブの「サブスクリプションの作成」をクリックします
  • 以下を設定します
  • トピック ARN: handson-order-events の ARN が自動で入っていることを確認
  • プロトコル: Amazon SQS
  • エンドポイント: 入力欄をクリックして一覧から handson-shipping-queue の ARN を選択(ARN を貼り付けてもかまいません)
  • その他の項目はデフォルトのままにし、「サブスクリプションの作成」をクリックします
  • サブスクリプションの詳細画面が開き、ステータスが「確認済み」と表示されます(同じアカウントの SQS キューは、確認の操作なしで自動的に確認済みになります)
  • トピックの詳細画面に戻り、同じ手順で、エンドポイントを handson-billing-queue の ARN にしたサブスクリプションを作成します
  • トピックの詳細画面の「サブスクリプション」タブに、2 つの SQS サブスクリプションが表示され、ステータスが「確認済み」になっていることを確認します
handson-order-events の「サブスクリプション」タブ(2 つの SQS サブスクリプションが確認済みになっている状態)
handson-order-events の「サブスクリプション」タブ(2 つの SQS サブスクリプションが確認済みになっている状態)

1 回の発行で 2 つのキューに届くことを確認する

  • トピック handson-order-events の詳細画面で「メッセージの発行」をクリックします
  • 以下を入力します
  • 件名: new-order
  • メッセージ本文(「メッセージ本文」セクションの「エンドポイントに送信するメッセージ本文」): order-100: banana x 10
  • 「メッセージの発行」をクリックします
  • SQS コンソールに戻り、左側ナビゲーションの「キュー」を選択します
  • handson-shipping-queue と handson-billing-queue の「利用可能なメッセージ」が、どちらも 1 になっていることを確認します(件数の反映に少し時間がかかるときは、一覧の更新アイコンをクリックします)
キュー一覧で handson-shipping-queue と handson-billing-queue の利用可能なメッセージがどちらも 1 になっている状態
キュー一覧で handson-shipping-queue と handson-billing-queue の利用可能なメッセージがどちらも 1 になっている状態
  • handson-shipping-queue を選択して「メッセージを送受信」をクリックし、「メッセージをポーリング」をクリックします(メッセージが表示されたら「ポーリングを停止」をクリックします)
  • 表示されたメッセージの ID をクリックし、「本文」タブを確認します。SNS から届いたメッセージは JSON 形式で、"Type" : "Notification"、"TopicArn"、"Subject" : "new-order"、"Message" : "order-100: banana x 10" などが含まれていることが確認できます
handson-shipping-queue で受信したメッセージの本文(SNS の JSON 形式で Message に order-100 が入っている状態)
handson-shipping-queue で受信したメッセージの本文(SNS の JSON 形式で Message に order-100 が入っている状態)
  • handson-billing-queue でも同様にポーリングし、同じ内容のメッセージが届いていることを確認します

1 回の発行で 2 つのキューに同じメッセージが届き、それぞれのキューから別々に受信できることが確認できます。

クラウドおさる

一度の掛け声で、発送係と請求係の注文箱の両方に同じ注文票が入ったでござる! SNS が配って、SQS が受け止める。この役割分担がファンアウトの肝でござるな。

まとめ

  • Amazon SQS はフルマネージドのメッセージキューサービスで、プロデューサーとコンシューマーを疎結合にする
  • メッセージは受信しただけでは消えず、可視性タイムアウトの間ほかのコンシューマーから見えなくなる。処理が終わったらコンシューマーが削除する
  • 標準キューは少なくとも 1 回の配信・ベストエフォートの順序でほぼ無制限のスループット、FIFO キューは送信順と 1 回のみの処理を保証する
  • 可視性タイムアウトの既定値は 30 秒(0 秒〜12 時間)、メッセージ保持期間の既定値は 4 日(1 分〜14 日)
  • ロングポーリング(受信待ち時間 1〜20 秒)を使うと、空の応答が減りコストを抑えられる可能性がある
  • デッドレターキューを設定すると、最大受信数を超えたメッセージを隔離して原因を調べられる。ソースキューと同じアカウント・リージョン・キュータイプにする
  • SNS はプッシュ型・1 対多、SQS はプル型でキューに保管する。SNS トピックに複数の SQS キューをサブスクライブするとファンアウト構成になり、キュー側のアクセスポリシーで SNS からの sqs:SendMessage を許可する必要がある

参照先

キャリア相談
クラウドおさる

独学の先に、AWS の仕事がある ── ジュニアおさるのキャリア相談

CLF には受かったけれど、次に何をすればいいのか分からない。独学で AWS を学ぶジュニアおさるの相談に、株式会社ジェニュイン代表の土肥が答えています。

  • ✓資格はゴールか、CLF の次に何から手を付けるか
  • ✓EC2 の次に作ってみる構成と、IaC・コスト管理
  • ✓実務経験ゼロでも、面接で話せる「これまで」の作り方
新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次