非同期呼び出し - AWS Lambda

非同期呼び出し

Amazon Simple Storage Service (Amazon S3) や Amazon Simple Notification Service (Amazon SNS) などの複数の AWS のサービスでは、関数を非同期的に呼び出してイベントを処理します。関数を非同期的に呼び出す場合は、関数コードからのレスポンスを待機しません。イベントを Lambda に渡すと、Lambda が残りを処理します。Lambda でエラーを処理する方法を設定し、呼び出しレコードをダウンストリームのリソースに送信して、アプリケーションのコンポーネントを連鎖させることができます。

Lambda が非同期呼び出しを処理する方法

次の図は、クライアントによる Lambda 関数の非同期的呼び出しを示しています。Lambda は、イベントを関数に送信する前にキューに入れます。


        クライアントは、関数を非同期的に呼び出します。Lambda は、イベントを関数に送信する前にキューに入れます。

非同期呼び出しの場合、Lambda はリクエストをキューに入れ、追加情報のない成功のレスポンスを返します。別のプロセスがキューからイベントを読み取って関数に送信します。関数を非同期的に呼び出すには、呼び出しタイプパラメータを Event に設定します。

aws lambda invoke \ --function-name my-function \ --invocation-type Event \ --cli-binary-format raw-in-base64-out \ --payload '{ "key": "value" }' response.json

AWS CLI バージョン 2 を使用している場合、cli-binary-format オプションは必須です。このオプションは、AWS CLI 設定ファイルで設定することもできます。

{ "StatusCode": 202 }

出力ファイル (response.json) には情報は含まれないものの、このコマンドを実行すると作成されます。Lambda がイベントをキューに追加することができない場合、エラーメッセージがコマンド出力に表示されます。

Lambda は関数の非同期イベントキューを管理し、エラー発生時に再試行を行います。関数からエラーが返された場合、Lambda はその関数をさらに 2 回再試行します。その際、最初の 2 回の試行の間に 1 分間、2 回目と 3 回目の間に 2 分間の待機時間があります。関数エラーには、関数のコードによって返されるエラーと、タイムアウトなど関数のランタイムによって返されるエラーが含まれます。


        Lambda は、各試行をサブセグメントに記録します。

関数にすべてのイベントを処理するために十分な同時実行数がない場合は、追加のリクエストはスロットリングされます。スロットルエラー (429) およびシステムエラー (500 番台) の場合、Lambda はイベントをキューに返し、最大 6 時間、関数を再度実行しようとします。再試行間隔は、最初の試行後 1 秒から最大 5 分まで指数関数的に増加します。キューに多くのエントリが含まれている場合、Lambda は再試行の間隔を長くして、キューからイベントを読み取る速度を低下させます。

次の例は、キューに正常に追加されたイベントが、スロットリングのために 1 時間後も保留になっている状態を示しています。


        スロットリングされたリクエストは、AWS X-Ray に保留中として表示されます。

関数がエラーを返さない場合でも、キュー自体は最終的に一貫しているため、同じイベントを Lambda から複数回受信する可能性があります。関数が受信するイベントに対応できない場合、イベントは関数に送信されずにキューから削除される場合があります。関数コードが重複イベントを適切に処理し、すべての呼び出しを処理するのに十分な同時実行数があることを確認してください。

キューが非常に長い場合、新しいイベントは Lambda によって関数に送信される前に期限切れになる場合があります。期限切れになったイベントや、すべての処理試行に失敗したイベントは Lambda によって破棄されます。関数のエラー処理を設定して、Lambda による再試行の回数を減らしたり、未処理のイベントをより速やかに破棄したりできます。

また、呼び出しレコードを別のサービスに送信するように Lambda を設定することもできます。Lambda は、非同期呼び出しの次の送信先をサポートしています。

  • Amazon SQS — 標準の SQS キュー。

  • Amazon SNS - SNS トピック。

  • AWS Lambda — Lambda 関数。

  • Amazon EventBridge - Amazon EventBridge イベントバス。

呼び出しレコードには、JSON 形式のリクエストとレスポンスに関する詳細が含まれます。処理に成功したイベント用とすべての処理試行に失敗したイベント用に別々の送信先を設定できます。または、破棄されたイベント用に Amazon SQS キューまたは Amazon SNS トピックをデッドレターキューとして設定することもできます。デッドレターキューの場合、Lambda はイベントのコンテンツのみを送信し、レスポンスの詳細は送信しません。

注記

関数がトリガーされないようにするには、その関数の予約済同時実行数をゼロに設定します。非同期で呼び出された関数の予約済同時実行数をゼロに設定すると、Lambda は設定したデッドレターキューまたは障害発生時のイベント送信先に再試行なしですぐにすべてのイベントを送信します。予約済同時実行数をゼロに設定している間に送信されたイベントを処理するには、デッドレターキューまたは障害発生時のイベント送信先からイベントを消費する必要があります。

非同期呼び出しのエラー処理の設定

Lambda コンソールを使用して、関数、バージョン、またはエイリアスのエラー処理を設定します。

エラー処理を設定するには

  1. Lambda コンソールで [Functions (関数)] ページを開きます。

  2. 関数を選択します。

  3. [設定]、[Asynchronous invocation (非同期呼び出し)] の順に選択します。

  4. [Asynchronous invocation (非同期呼び出し)] で、[Edit (編集)] を選択します。

  5. 以下を設定します。

    • [Maximum age of event] (イベントの最大有効期間) - Lambda が非同期イベントキューにイベントを保持する最大時間 (最大 6 時間)。

    • [Retry attempts] (再試行) - 関数がエラーを返したときに Lambda が再試行する回数 (0 〜 2)。

  6. [Save] を選択します。

呼び出しイベントが最大有効期間を超えるか、すべての再試行に失敗すると、Lambda はそのイベントを破棄します。破棄されたイベントのコピーを保持するには、失敗したイベントの送信先を設定します。

非同期呼び出しの送信先の設定

非同期呼び出しのレコードを別のサービスに送信するには、関数に送信先を追加します。処理に失敗したイベントと正常に処理されたイベントに別々の送信先を設定できます。エラー処理の設定と同様に、関数、バージョン、またはエイリアスに対して送信先を設定できます。

次の例は、非同期呼び出しを処理する関数を示しています。関数が成功レスポンスを返すか、エラーをスローせずに終了すると、Lambda は呼び出しのレコードを EventBridge イベントバスに送信します。イベントがすべての処理試行に失敗すると、Lambda は呼び出しレコードを Amazon SQS キューに送信します。


        Lambda は、結果に応じて、呼び出しレコードをキューまたはイベントバスの送信先に送信します。

送信先にイベントを送信するには、関数に追加のアクセス許可が必要です。関数の実行ロールに必要なアクセス権限と持つポリシーを追加します。各送信先サービスには、次のように異なるアクセス許可が必要です。

Lambda コンソールの [Function Visualization] (関数の可視化) で、関数に送信先を追加します。

非同期呼び出しレコードの送信先を設定するには

  1. Lambda コンソールで [Functions (関数)] ページを開きます。

  2. 関数を選択します。

  3. [機能の概要 ] で、[送信先を追加 ] を選択します。

  4. [Source (送信元)] で、[Asynchronous invocation (非同期呼び出し)] を選択します。

  5. [条件] で、以下のオプションから選択します。

    • [On failure] (失敗時) - イベントがすべての処理試行に失敗した場合、または最大有効期間を超えた場合に、レコードを送信します。

    • [On success] (正常) - 関数が非同期呼び出しを正常に処理したときに、レコードを送信します。

  6. [送信先タイプ] で、呼び出しレコードを受信するリソースのタイプを選択します。

  7. [送信先] で、リソースを選択します。

  8. [Save] を選択します。

呼び出しが条件に一致すると、Lambda は呼び出しに関する詳細を含む JSON ドキュメントを送信先に送ります。次の例は、関数エラーが原因で 3 つの処理試行に失敗したイベントの呼び出しレコードを示しています。

例 呼び出しレコード

{ "version": "1.0", "timestamp": "2019-11-14T18:16:05.568Z", "requestContext": { "requestId": "e4b46cbf-b738-xmpl-8880-a18cdf61200e", "functionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:$LATEST", "condition": "RetriesExhausted", "approximateInvokeCount": 3 }, "requestPayload": { "ORDER_IDS": [ "9e07af03-ce31-4ff3-xmpl-36dce652cb4f", "637de236-e7b2-464e-xmpl-baf57f86bb53", "a81ddca6-2c35-45c7-xmpl-c3a03a31ed15" ] }, "responseContext": { "statusCode": 200, "executedVersion": "$LATEST", "functionError": "Unhandled" }, "responsePayload": { "errorMessage": "RequestId: e4b46cbf-b738-xmpl-8880-a18cdf61200e Process exited before completing request" } }

呼び出しレコードには、イベント、レスポンス、レコードが送信された理由に関する詳細が含まれます。

非同期呼び出し設定 API

AWS CLI または AWS SDK で非同期呼び出し設定を管理するには、以下の API オペレーションを使用します。

AWS CLI で非同期呼び出しを設定するには、put-function-event-invoke-config コマンドを使用します。以下の例では、最大イベント有効期間が 1 時間で再試行なしの関数を設定しています。

aws lambda put-function-event-invoke-config --function-name error \ --maximum-event-age-in-seconds 3600 --maximum-retry-attempts 0

次のような出力が表示されます。

{ "LastModified": 1573686021.479, "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:error:$LATEST", "MaximumRetryAttempts": 0, "MaximumEventAgeInSeconds": 3600, "DestinationConfig": { "OnSuccess": {}, "OnFailure": {} } }

put-function-event-invoke-config コマンドは、関数、バージョン、またはエイリアスの既存の設定を上書きします。他の設定をリセットしないでオプションを設定するには、update-function-event-invoke-config を使用します。以下の例では、イベントを処理できない場合に、destination という名前の SQS キューにレコードを送信するように Lambda を設定します。

aws lambda update-function-event-invoke-config --function-name error \ --destination-config '{"OnFailure":{"Destination": "arn:aws:sqs:us-east-2:123456789012:destination"}}'

次のような出力が表示されます。

{ "LastModified": 1573687896.493, "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:error:$LATEST", "MaximumRetryAttempts": 0, "MaximumEventAgeInSeconds": 3600, "DestinationConfig": { "OnSuccess": {}, "OnFailure": { "Destination": "arn:aws:sqs:us-east-2:123456789012:destination" } } }

デッドレターキュー

障害発生時の送信先に代わる方法として、配信不能キューを使用して関数を設定し、破棄されたイベントを保存してさらに処理できます。配信不能キューは、イベントがすべての処理試行に失敗した場合や処理されずに期限切れになった場合に使用されるという点で、障害発生時の送信先と同じように動作します。ただし、配信不能キューは関数のバージョン固有の設定の一部であるため、バージョンを公開するとロックされます。また、障害発生時の送信先は、追加のターゲットをサポートし、関数のレスポンスに関する詳細を呼び出しレコードに含めます。

デッドレターキュー内のイベントを再処理するには、デッドレターキューを Lambda 関数のイベントソースとして設定します。または、イベントを手動で取得することもできます。

デッドレターキューには Amazon SQS キューまたは Amazon SNS トピックを選択できます。キューまたはトピックがない場合は、新規に作成します。ユースケースに一致するターゲットタイプを選択します。

  • Amazon SQS キュー - キューは、失敗したイベントが取得されるまでそれらを保持します。Lambda 関数や CloudWatch アラームなどの単一のエンティティが失敗したイベントを処理することが予想される場合は、Amazon SQS キューを選択します。詳細については、「Amazon SQS で AWS Lambda を使用する」を参照し、関数を呼び出してください。

    Amazon SQS コンソールで、キューを作成します。

  • Amazon SNS トピック - トピックは、失敗したイベントを1 つまたは複数の送信先に中継します。複数のエンティティが失敗したイベントに対して動作することが予想される場合は、Amazon SNS トピックを選択します。例えば、E メールアドレス、Lambda 関数、および/または HTTP エンドポイントにイベントを送信するようにトピックを設定できます。詳細については、「Amazon SNS での Lambda の使用」を参照してください。

    Amazon SNS コンソールでトピックを作成します。

キューまたはトピックにイベントを送信するには、関数に追加のアクセス権限が必要です。関数の実行ロールに必要なアクセス権限と持つポリシーを追加します。

ターゲットキューまたはトピックがカスタマー管理のキーで暗号化されている場合、その実行ロールはキーのリソースベースのポリシーのユーザーでもある必要があります。

ターゲットを作成し、関数の実行ロールを更新した後、デッドレターキューを関数に追加します。同じターゲットにイベントを送信するように複数の関数を設定できます。

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

  1. Lambda コンソールで [Functions (関数)] ページを開きます。

  2. 関数を選択します。

  3. [設定]、[Asynchronous invocation (非同期呼び出し)] の順に選択します。

  4. [Asynchronous invocation (非同期呼び出し)] で、[Edit (編集)] を選択します。

  5. [DLQ resource] (DLQ リソース) を [Amazon SQS] または [Amazon SNS] に設定します。

  6. ターゲットとなるキューまたはトピックを選択します。

  7. [Save] を選択します。

AWS CLI を使用してデッドレターキューを設定するには、update-function-configuration コマンドを使用します。

aws lambda update-function-configuration --function-name my-function \ --dead-letter-config TargetArn=arn:aws:sns:us-east-2:123456789012:my-topic

Lambda は、イベントをそのまま属性の追加情報と共にデッドレターキューに送信します。この情報を使用して、関数が返したエラーを特定するか、イベントをログまたは AWS X-Ray トレースと関連付けることができます。

デッドレターキューメッセージの属性

  • RequestID (文字列) - 呼び出しリクエストの ID。リクエスト ID は関数ログに表示されます。また、X-Ray SDK を使用して、トレース内の属性のリクエスト ID を記録することもできます。その後、X-Ray コンソールで、リクエスト ID によってトレースを検索できます。例については、「エラープロセッサのサンプル」を参照してください。

  • ErrorCode (数値) - HTTP ステータスコード。

  • ErrorMessage (文字列) - エラーメッセージの最初の 1 KB。


        Amazon SQS コンソールのデッドレターキューイベントの属性。

Lambda がデッドレターキューにメッセージを送信できない場合、イベントは削除され、DeadLetterErrors メトリクスが発行されます。このような状況は、アクセス権限がない、またはメッセージの合計サイズがターゲットとなるキューやトピックの制限を超えてしまった場合に発生します。例えば、本文が 256 KB に近い Amazon SNS 通知でエラーが発生する関数がトリガーされた場合、Amazon SNS によって追加された追加のイベントデータが Lambda によって追加された属性と組み合わされることで、メッセージがデッドレターキューで許容されている最大サイズを超過することがあります。

Amazon SQS をイベントソースとして使用する場合、Amazon SQS キューでは Lambda 関数ではなくデッドレターキューを設定します。詳細については、「Amazon SQS で AWS Lambda を使用する」を参照してください。