SQS イベントソースに関連するエラーを処理する際に、Lambda はバックオフ戦略を備えた再試行戦略を自動的に使用します。また、部分的なバッチレスポンスを返すように SQS イベントソースマッピングを設定することで、エラー処理の動作をカスタマイズすることもできます。
失敗した呼び出しに対するバックオフ戦略
呼び出しが失敗すると、Lambda はバックオフ戦略の実装中に呼び出しの再試行を試みます。バックオフ戦略は、Lambda で発生した障害が関数コード内のエラーによるものか、スロットリングによるものかに応じて若干異なります。
-
関数コードが原因でエラーが発生した場合、Lambda は呼び出しの処理と再試行を停止します。その間、Lambda は Amazon SQS イベントソースマッピングに割り当てられた同時実行数を減らすことで、再試行を徐々にバックオフします。キューの可視性タイムアウトがタイムアウトすると、メッセージが再びキューに表示されます。
-
スロットリングが原因で呼び出しが失敗する場合、Lambda は Amazon SQS イベントソースマッピングに割り当てられた同時実行数を減らすことで、再試行を徐々にバックオフします。Lambda は、メッセージのタイムスタンプがキューの可視性タイムアウトを超過するまでメッセージを再試行し続けますが、タイムアウトした時点でメッセージをドロップします。
部分的なバッチレスポンスの実装
Lambda 関数がバッチを処理しているときにエラーが発生すると、デフォルトでそのバッチ内のすべてのメッセージが再度キューに表示され、これには Lambda が正常に処理したメッセージも含まれます。その結果、関数が同じメッセージを複数回処理することになる場合があります。
失敗したバッチ内の正常に処理されたメッセージを再処理しないようにするために、失敗したメッセージのみを再び表示するようにイベントソースマッピングを設定できます。これを部分的なバッチレスポンスと呼びます。部分的なバッチレスポンスをオンにするには、イベントソースマッピングを設定するときに FunctionResponseTypes アクション用に ReportBatchItemFailures
を指定します。そうすると、関数が部分的な成功を返すようになるため、レコードでの不必要な再試行回数を減らすことができます。
ReportBatchItemFailures
がアクティブ化されている場合、Lambda は、関数の呼び出しが失敗したときにメッセージポーリングをスケールダウンしません。一部のメッセージが失敗することが想定され、それらの失敗によってメッセージの処理レートに影響が及ばないようにする場合は、ReportBatchItemFailures
を使用します。
注記
部分的なバッチレスポンスを使用する場合は、次の点に注意してください。
-
関数が例外をスローする場合、バッチ全体が完全な失敗とみなされます。
-
この機能を FIFO キューで使用している場合、関数は最初の失敗後にメッセージの処理を停止し、
batchItemFailures
で失敗したメッセージと未処理のメッセージのすべてを返します。これは、キュー内のメッセージの順序を維持するのに役立ちます。
部分的なバッチレポートをアクティブ化するには
-
次のコマンドを実行して、関数用に
ReportBatchItemFailures
をアクティブ化します。イベントソースマッピングの UUID を取得するには、list-event-source-mappings AWS CLI コマンドを実行します。aws lambda update-event-source-mapping \ --uuid
"a1b2c3d4-5678-90ab-cdef-11111EXAMPLE"
\ --function-response-types"ReportBatchItemFailures"
-
関数コードを更新して、すべての例外をキャッチし、失敗したメッセージを
batchItemFailures
JSON レスポンスで返します。batchItemFailures
レスポンスには、メッセージ ID のリストがitemIdentifier
JSON 値として含まれている必要があります。例えば、メッセージ ID が
id1
、id2
、id3
、id4
、およびid5
である 5 つのメッセージのバッチがあるとします。関数は、id1
、id3
、id5
を正常に処理します。メッセージid2
およびid4
がキューで再び表示されるようにするには、関数が次のレスポンスを返す必要があります。{ "batchItemFailures": [ { "itemIdentifier": "id2" }, { "itemIdentifier": "id4" } ] }
バッチで失敗したメッセージ ID のリストを返す関数コードの例を次に示します。
- SDK for .NET
-
注記
GitHub には、その他のリソースもあります。サーバーレスサンプル
リポジトリで完全な例を検索し、設定および実行の方法を確認してください。 .NET を使用した Lambda での SQS バッチアイテム失敗のレポート。
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 using Amazon.Lambda.Core; using Amazon.Lambda.SQSEvents; // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace sqsSample; public class Function { public async Task<SQSBatchResponse> FunctionHandler(SQSEvent evnt, ILambdaContext context) { List<SQSBatchResponse.BatchItemFailure> batchItemFailures = new List<SQSBatchResponse.BatchItemFailure>(); foreach(var message in evnt.Records) { try { //process your message await ProcessMessageAsync(message, context); } catch (System.Exception) { //Add failed message identifier to the batchItemFailures list batchItemFailures.Add(new SQSBatchResponse.BatchItemFailure{ItemIdentifier=message.MessageId}); } } return new SQSBatchResponse(batchItemFailures); } private async Task ProcessMessageAsync(SQSEvent.SQSMessage message, ILambdaContext context) { if (String.IsNullOrEmpty(message.Body)) { throw new Exception("No Body in SQS Message."); } context.Logger.LogInformation($"Processed message {message.Body}"); // TODO: Do interesting work based on the new message await Task.CompletedTask; } }
失敗したイベントがキューに戻らない場合は、AWS ナレッジセンターの「Lambda 関数 SQS ReportBatchItemFailures をトラブルシューティングするにはどうすればよいですか?
成功条件と失敗の条件
関数が以下のいずれかを返す場合、Lambda はバッチを完全な成功として扱います。
-
空の
batchItemFailures
リスト -
null の
batchItemFailures
リスト -
空の
EventResponse
-
null の
EventResponse
関数が以下のいずれかを返す場合、Lambda はバッチを完全な失敗として扱います。
-
無効な JSON レスポンス
-
空の文字列
itemIdentifier
-
ヌル
itemIdentifier
-
不正なキー名を持つ
itemIdentifier
-
存在しないメッセージ ID を持つ
itemIdentifier
値
CloudWatch メトリクス
関数がバッチ項目の失敗を正しく報告しているかどうかを判断するために、Amazon SQS メトリクスの NumberOfMessagesDeleted
および ApproximateAgeOfOldestMessage
を Amazon CloudWatch でモニタリングできます。
-
NumberOfMessagesDeleted
は、キューから削除されたメッセージの数を追跡します。これが 0 になるということは、関数レスポンスが失敗したメッセージを正しく返していないことを示唆しています。 -
ApproximateAgeOfOldestMessage
は、最も古いメッセージがキューに残っている期間を追跡します。このメトリクスの急激な増加は、関数が失敗したメッセージを正しく返していないことを示唆している可能性があります。