[アップデート] AWS Trusted Advisor で Lambda 関数の非同期呼び出し時のエラーハンドリング設定がされているか確認出来るようになりました

2023.09.06

いわさです。

AWS Trusted Advisor は構築済みリソースの構成状態から改善のための推奨事項を提案してくれるサービスです。
また、AWS Support プランがビジネス以上の場合には、Trusted Advisor で耐障害性など追加の推奨事項を得ることも出来ます。

本日のアップデートで AWS Trusted Advisor の耐障害性に関するチェック項目として「AWS Lambda On Failure Event Destinations」が追加されました。

このチェック項目を使うことで、エラーハンドリングの仕組みが設定されていない非同期呼び出し用 Lambda 関数を検出することが出来ます。

Lambda の非同期呼び出しとエラーハンドリング

はじめにおさらいですが、Lambda 関数の実行には同期呼び出しと非同期呼び出しがあります。
デフォルトでは Lambda は関数を同期的に呼び出します。一方、InvocationType に Event を設定することで非同期呼び出しを行うことも出来ます。
InvokeAsyncで非同期呼び出しを行うことも出来ますが、現在は非推奨となっています)

この時 Lambda 関数で呼び出し後にエラーが発生した場合、前者の場合は呼び出し元にエラーレスポンスが返却されるので適宜エラー処理を行うことが出来ます。
しかし、後者については非同期で呼び出されるので呼び出し元は Lambda 関数の非同期呼び出しに成功したことしか受け取らず、関数が生成するレスポンスを同期的に受け取ることは出来ません。

これを対処する方法として Lambda 関数には「送信先」機能と「デッドレターキュー」機能が用意されています。

これらを設定しておくことで、非同期実行されている Lambda 関数で異常が起きた際に SQS や SNS などにエラーメッセージが送信されるため、非同期的にエラー処理(ロールバックや再試行、通知など)を行うことが出来ます。

AWS Trusted Advisor 上での確認方法

実際に AWS Trusted Advisor での見え方を確認してみました。
なお、本日時点で AWS Trusted Advisor 公式ドキュメント上にはまだこのチェック項目の情報が記載されておらず、列挙される関数の条件などの仕様が不明です。

AWS Trusted Advisor では耐障害性チェックカテゴリから確認することが出来ます。

次の環境にはいくつもの Lambda 関数が存在していますが、対象の関数が表示されていませんでした。
おそらく、過去一定期間のasync-invokeの履歴などから対象は列挙されているのではないでしょうか。

また、問題のあるアカウントの場合は次のようにアラートが表示されています。
アラートのレベルは警告となっています。

対象の関数を確認出来るのはもちろんですが、以下の情報から実行頻度やドロップされたリクエストの割合や数なども確認することが出来ます。

  • Current day async requests dropped percentage
  • Current day async requests
  • Average daily async requests dropped percentage
  • Average daily async requests

これは非常に良いですね。
例えば、次のような失敗率が 100% のものなどは、非同期呼び出しが結構な頻度で行われていますが全て失敗しており、さらにエラーハンドリングが実装されていない状態を示しています。

実際に対象の Lambda 関数のメトリクスを確認してみると、全ての非同期呼び出しの結果が失敗していますね。

100% 失敗するものについては、明らかに実装や構成などどこかおかしいことが多いので逆にエラーハンドリングしなくてもログから原因を分析して対処するだけで良い場合もあると思いますが、中途半端に失敗している再現性が低いものは特定条件時のみ発生したりリトライすると復旧する場合などがあるので、こういったものは適切なエラーハンドリングの仕組みは必須な感じがしますね。気づかずに一部だけ失敗している状況の可能性が高い気がします。

冒頭のブログ記事で詳しい設定方法は紹介されていますが、失敗時送信先の追加は次のように行うことが出来ます。

なお、失敗時送信先の場合は次のようなメッセージが送信されます。
こちらはメッセージ内容から、デバッグに使いやすい感じでしょうか。

{
    "version": "1.0",
    "timestamp": "2023-09-05T20:56:53.394Z",
    "requestContext": {
        "requestId": "bcb5a8e1-8515-4ca7-ba5a-84080e4113a2",
        "functionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:hoge0906lambda3:$LATEST",
        "condition": "RetriesExhausted",
        "approximateInvokeCount": 1
    },
    "requestPayload": {
        "hoge1": "value1"
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "responsePayload": {
        "errorType": "ReferenceError",
        "errorMessage": "x is not defined",
        "trace": [
            "ReferenceError: x is not defined",
            " at Runtime.handler (file:///var/task/index.mjs:7:3)",
            " at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1147:29)"
        ]
    }
}

デッドレターキューの場合は次のように設定が可能です。

デッドレターキューの場合は次のようなメッセージとなっています。リトライに使いやすそうです。

{
    "hoge1": "value1"
}

さいごに

本日は AWS Trusted Advisor で Lambda 関数の非同期呼び出し時のエラーハンドリング設定がされているか確認出来るようになったので確認してみました。

非同期呼び出し用のエラーハンドリング設定はデフォルトだと再試行回数くらいで、他は何もされていない状態です。
知らずにそのまま使っている方も多いのではないでしょうか。

Trusted Advisor のフル機能を使える方であれば追加の料金は不要でチェック出来ますのでぜひ確認してみてください。