ラムダ目的地は非同期ラムダ関数のための成功とエラー処理を改善する

14443 ワード

私は、この特徴があったので、ここでパーティーに少し遅れるかもしれませんannounced in late 2019 , しかし、Serverlessなスペースでそんなに多くのことが起こっているので、私は、私がまだそれで遊ぶ機会がなかったただ一人の人でないかもしれないと思いました.このポストでは、目的地の機能、意図したユースケースを説明します、そして、あなたが単純なデモ・アプリケーションを通してそれを使うとき、あなたは何を予想することができますか.私はストリームベースの呼び出しのための目的地についてはここではあまりにも多くのポストこのポストの範囲を増加する話をしません.もう一つの時間.興味があれば教えてください.
宛先は非同期で呼び出されるラムダ関数に便利です.これは、関数が起動されることを意味しますが、それをトリガするパーティは、機能が完了する前に終了するのを待ちません.この例はS 3からの呼び出しである.オブジェクトがバケットにアップロードされたので、S 3がラムダ関数をトリガーするとき、それが結果について気にしないので、ラムダ関数が何をしているかを終えるのを待ちません.
フードの下で、これは呼び出しタイプを使用しますEvent で指定されるAPI documentation . APIの呼び出し元は通常、HTTP 202 要求が受け入れられたことを示す応答.AWS CLIを使ってこのような関数を呼び出すことができます.以下に例を示します.
$ aws lambda invoke --function-name LambdaDemo --invocation-type Event --no-cli-pager /dev/null
{
    "StatusCode": 202
}
非同期呼び出しは、イベント呼び出しのメインブロックをブロックしないため、すぐに関数呼び出し結果を必要としない場合に優れています.どちらのプロセスが関数をトリガーするかは、ほとんどどんな遅れもせずにその仕事を続けることができます.ラムダサービスはバックグラウンドで実行を管理します.それはエラーの場合には潜在的なリトライを含みます.これは良いですが、それはしばしば全体の物語ではない.通常、我々は今の結果については気にしないが、いくつかの時点で、何が起こったのか知りたい.
過去に、我々がそれをすることができたいくつかの方法がありました.ラムダは、再試行した後でさえ耐える失敗を送ることができましたdead-letter queue 後の評価のために.それは失敗に適していますが、あなたの関数コードの中から他のサービスや関数をトリガすることに加えて、成功した呼び出しに応答する良い方法はありませんでした.目的地はかなりこの状況を改善します.
ラムダの目的地では、非同期呼び出しが成功したり失敗した場合に何をすべきかを指定できます.これらのイベントを処理するために、ラムダ関数、SNSトピック、SQSキュー、またはEventBridgeイベントバスのいずれかに情報を渡すことができます.これにより、関数コードから成功したロジックを処理する部分を削除し、サービスを処理させることができます.また、SQSでエラーを捕捉するよりも適切であるかもしれない異なったエラー処理メカニズムへのドアを開きます.

このアプリを行うことができますを表示するデモアプリを構築しましょう.私は2つのラムダ関数を展開するCDKアプリを作成しました.あなたはそのコードを見つけることができますcompanion repository on Github . つの関数は送信者として機能し、もう一方は受信機です.受信機能は、送付者の成功と失敗目的地のために構成されます.

送信者関数はかなり基本的であり、成功した場合、または受け取ったイベントに基づいて例外を送出します.
from typing import Any

# We expect events in this form:
# {"return": "failure|success"}
def lambda_handler(event: dict, context: Any) -> dict:

    if event.get("return", "failure") == "failure":
        # By default we return a failure
        raise RuntimeError("I'm supposed to fail here")
    else:
        return {"this_invocation": "was_successful"}

受信機はそれよりも簡単です、それは入力として受け取るイベントを印刷するだけです.
import json
from typing import Any

def lambda_handler(event: dict, context: Any) -> dict:
    print(json.dumps(event))
CDKアプリの展開は、AWS CLI(V 2)を非同期に送信する2つの出力を生成します.関数名はあなたのために異なるかもしれません.
$ cdk deploy
# [,,,]
Outputs:
CdkLambdaDestinationsStack.invokefailure = aws lambda invoke --function-name CdkLambdaDestinationsStack-sender96A36763-zpInOlEaxILF --invocation-type Event --payload 'eyJyZXR1cm4iOiAiZmFpbHVyZSJ9' --no-cli-pager /dev/null
CdkLambdaDestinationsStack.invokesuccess = aws lambda invoke --function-name CdkLambdaDestinationsStack-sender96A36763-zpInOlEaxILF --invocation-type Event --payload 'eyJyZXR1cm4iOiAic3VjY2VzcyJ9' --no-cli-pager /dev/null
Stack ARN:
# [...]
次に、CDK出力が表示される2つのコマンドを実行し、受信機関数のCloudWatchログを検査します.ここでは、受信者が失敗した呼び出しを受け取るイベントを見ることができます.
{
    "version": "1.0",
    "timestamp": "2022-04-16T11:24:43.658Z",
    "requestContext": {
        "requestId": "17b37350-871d-4d69-9b4f-a77c2ddd7fc9",
        "functionArn": "arn:aws:lambda:eu-central-1:123123123123:function:CdkLambdaDestinationsStack-sender96A36763-zpInOlEaxILF:$LATEST",
        "condition": "RetriesExhausted",
        "approximateInvokeCount": 3
    },
    "requestPayload": {
        "return": "failure"
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "responsePayload": {
        "errorMessage": "I'm supposed to fail here",
        "errorType": "RuntimeError",
        "requestId": "17b37350-871d-4d69-9b4f-a77c2ddd7fc9",
        "stackTrace": [
            "  File \"/var/task/sender_handler.py\", line 9, in lambda_handler\n    raise RuntimeError(\"I'm supposed to fail here\")\n"
        ]
    }
}
ラムダ関数の元のペイロードが渡され、スタックトレースを含む詳細なエラーメッセージが表示されます.さらに、我々は我々のデバッグ努力を助けるために要求IDとより多くの情報を得ます.成功した呼び出しのために、我々はより少ない情報を受けます.しかしながら、ラムダ関数をデバッグしたいならば、我々が必要とすることができるすべてがまだあります.それに加えて、さらなる処理のために使用できるラムダ関数の入出力を見ます.
{
    "version": "1.0",
    "timestamp": "2022-04-16T11:28:07.537Z",
    "requestContext": {
        "requestId": "04e16a9b-93b2-4404-bbca-bc29174796ef",
        "functionArn": "arn:aws:lambda:eu-central-1:123123123123:function:CdkLambdaDestinationsStack-sender96A36763-zpInOlEaxILF:$LATEST",
        "condition": "Success",
        "approximateInvokeCount": 1
    },
    "requestPayload": {
        "return": "success"
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST"
    },
    "responsePayload": {
        "this_invocation": "was_successful"
    }
}

また、元のラムダ関数の入力を宛先に渡すのを止めることも可能です.私の場合、私はそれを通過するデフォルトに立ち往生しました.あなたの入力のデータの種類に応じて、それは非常に敏感ならばそれを通過しない慎重にすることがあります.
興味深いエッジケースはFIFOキューとトピックに関するものです.いくつかの理由で、FIFOのSNSのトピックは、ラムダの宛先としてサポートされているFIFOのSQSキューがない.
本稿では、非同期呼び出しのためのラムダ目的地を調査した.私たちは、どの問題を解決するか、どのようにそれらを使用することができるかを学びました.
うまくいけば、この記事から何か役に立つことを学んだ.すべての質問については、フィードバックや懸念は、私には、社会的なメディアのチャンネルを介して私のバイオに記載されて手を差し伸べる自由に感じる.
更なる読書
  • Lambda Destinations Launch Blog Post
  • Lambda Destinations Documentation