WEB問題集
請求サービスのワーカーは、SQS 標準キューから受け取った注文のメッセージから、1 件あたり約 2 分かけて請求書を作成しています。最近、同じ注文の請求書が二重に作成され、検査でエラーが記録されています。
請求書は、1 件のメッセージにつき 1 回だけ作成する必要があります。
この問題の原因として考えられるものはどれですか。
解説
【正解: A】の理由
可視性タイムアウトは、受信したメッセージをほかのコンシューマーから見えなくしておく期間で、キューの既定値は 30 秒です。この期間内に削除されなかったメッセージはキューに再び現れ、別のワーカーが受け取れる状態になります。そのため、処理に約 2 分かかるのに既定値のままだと、処理中のメッセージが別のワーカーにも渡り、同じ請求書が二重に作成されます。したがって、処理時間に合わせて可視性タイムアウトを延ばす必要があります。
【他選択肢が違う理由】
- B: 保持期間が短いと、メッセージは受信の前に消えます。そのため、請求書は二重には作成されません。
- C: ロングポーリングは空の受信を減らす設定です。そのため、同じメッセージを再び渡す原因になりません。
- D: 作成後に DeleteMessage で削除するのは正しい手順です。そのため、二重の処理の原因になりません。
【参考】
注文サービスは、注文が確定すると在庫・配送・ポイントの 3 つのサービスの API を順番に同期で呼び出しています。サービスを 1 つ加えるたびに、注文サービスに呼び出しの処理を書き足してきました。今後も、こうしたサービスは増える見込みです。
新しいサービスを加えるときに、注文サービスのコードを変えずに済む構成にする必要があります。
この要件を満たすために、デベロッパーは何をすべきですか。
解説
【正解: D】の理由
SNS トピックに発行されたメッセージは、トピックをサブスクライブしている SQS キューのそれぞれに届けられます。そのため、注文サービスはトピックに 1 回発行するだけでよく、各サービスは自分のキューから自分のペースで受け取れます。さらに、新しいサービスは自分のキューをトピックにサブスクライブするだけで加われるので、注文サービスのコードを変える必要がありません。この構成により、注文サービスと各サービスの結合がゆるやかになります。
【他選択肢が違う理由】
- A: 並列にしても、各サービスを直接呼び出す作りは残ります。そのため、追加のたびにコードが変わります。
- B: 1 つのキューのメッセージは、1 つのコンシューマーだけが処理します。そのため、3 つには届けられません。
- C: 非同期でも、呼び出し先の一覧はコードが持ちます。そのため、追加のたびにコードの変更が必要です。
【参考】
AWS Docs: Amazon SNS 通知の Amazon SQS キューへのファンアウトと非同期処理
AWS Docs: Amazon SQS のキューの種類
決済サービスは、決済が終わるたびに EventBridge のカスタムイベントバス - Classicへイベントを送信しています。イベントの detail には、金額を数値で表す amount が含まれます。承認ワークフローのステートマシンは作成済みです。
経理チームは、amount が 100000 以上の決済だけを Step Functions の承認ワークフローに送る必要があります。決済サービスはほかのチームが管理しており、送信するイベントの形は変えない方針です。
これらの要件を、最も少ないコードの変更で満たす解決策はどれですか。
解説
【正解: A】の理由
EventBridge のイベントパターンは、numeric の比較演算子で数値の範囲を照合できます。そのため、ルールに amount が 100000 以上という条件を書けば、該当する決済のイベントだけがターゲットに送られます。また、Step Functions のステートマシンはルールのターゲットに指定できるので、判定や呼び出しのコードを新たに書く必要がありません。さらに、決済サービスが送るイベントの形も今のまま使えます。
【他選択肢が違う理由】
- B: 判定と StartExecution のコードを新たに書く必要があります。そのため、変更は A より多くなります。
- C: キューを読む関数と判定のコードを作る必要があります。そのため、変更が最も少ない方法ではありません。
- D: 属性を加えるには、決済サービスの変更が必要です。これは、イベントの形を変えない方針に反します。
【参考】
AWS Docs: Amazon EventBridge のイベントパターンで使用する比較演算子
AWS Docs: Amazon EventBridge のイベントバスターゲット
写真共有アプリでは、Lambda 関数が利用者の画像を S3 バケットに保存したあと、同じ呼び出しの中でサムネイルを生成してから応答しています。サムネイルの生成には数秒かかり、その間、利用者は応答を待っています。
画像の保存とサムネイルの生成を切り離す解決策はどれですか。
解説
【正解: A】の理由
S3 は、オブジェクトの作成などのイベントが起きたときに、バケットの通知の設定に従って Lambda 関数を非同期で呼び出せます。そのため、アップロードを受ける関数は画像を保存した時点で応答を返し、サムネイルの生成は別の関数が受け持つ形にできます。これにより、保存の処理はサムネイルの生成の完了を待たなくなり、2 つの処理が切り離されます。なお、S3 が関数を呼び出せるように、関数のリソースベースのポリシーで S3 に許可を与えます。
【他選択肢が違う理由】
- B: スレッドを分けても、2 つの処理は同じ呼び出しの中に残ります。そのため、切り離されません。
- C: Transfer Acceleration はアップロードを速くする機能です。そのため、生成の処理を分けられません。
- D: プロビジョンド同時実行でも、処理は同じ呼び出しの中に残ります。そのため、両者は切り離されません。
【参考】
AWS Docs: Lambda を使用した Amazon S3 イベント通知の処理
AWS Docs: Lambda 関数を非同期的に呼び出す
Lambda の受付関数は、受け付けた申込みを記録したあと、審査関数を RequestResponse で呼び出し、審査関数が終わるまで待っています。審査には数分かかることがあり、その間は受付関数の実行時間も伸びます。
デベロッパーは、受付関数が審査関数の完了を待つ作りをやめ、2 つの関数を切り離そうとしています。
この目的を達成する手順はどれですか(2 つ選択してください)。
解説
【正解: A / E】の理由
A では、受付関数は申込みを SQS キューに送った時点で処理を終えるので、審査関数の完了を待たなくなります。一方、E では、Lambda のイベントソースマッピングがキューをポーリングし、取り出したメッセージで審査関数を呼び出します。そのため、2 つの関数はキューを挟んでつながり、互いの処理時間や停止の影響を直接受けません。なお、審査には数分かかるので、キューの可視性タイムアウトは審査関数のタイムアウトより長く設定します。
【他選択肢が違う理由】
- B: タイムアウトを延ばしても、受付関数は審査の完了まで待ち続けます。そのため、切り離されません。
- C: 審査関数の起動は早まりますが、呼び出しは同期のままです。そのため、待ち続ける作りは残ります。
- D: 2 つの関数をまとめると、記録と審査がさらに強く結び付きます。これは、目的とは逆の変更です。
【参考】
AWS Docs: Amazon SQS での Lambda の使用
AWS Docs: Lambda がストリームおよびキューベースのイベントソースからのレコードを処理する方法
