SJ blog
backend
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

Lambda宛先設定とDLQ — 非同期呼び出しの失敗ハンドリング

Lambda非同期呼び出しの成功/失敗時の宛先(Destinations)設定、DLQとの違い、最大試行回数、イベントエイジの上限、EventBridgeとSQSへのルーティングパターンを解説。

一言結論

Lambda非同期呼び出しの失敗ハンドリングは宛先設定(Destinations)を優先すべきで、DLQより豊富なメタデータを持ち成功時のルーティングも可能なため、新規設計ではDestinationsを使うのが正解だ。

Lambda の非同期呼び出しの仕組み

Lambdaを非同期で呼び出す(S3イベント、SNS、EventBridge等)場合、失敗時のハンドリング設計が重要だ。

非同期呼び出しの再試行:
  1回目実行 → 失敗
  待機(1分)→ 2回目実行 → 失敗
  待機(2分)→ 3回目実行 → 失敗(最大2回のリトライ)
  → 失敗イベントの送信先(DLQまたは宛先)

デフォルトの最大試行回数: 3回(1回 + 2回リトライ)
カスタマイズ可能範囲: 0〜2回のリトライ(合計1〜3回の実行)
最大イベントエイジ: デフォルト6時間(60〜21600秒)

宛先設定(Destinations)

Lambda宛先は成功・失敗それぞれに設定でき、DLQより詳細な情報を保持する。

# Lambda宛先の設定
aws lambda put-function-event-invoke-config \
  --function-name my-function \
  --maximum-retry-attempts 2 \
  --maximum-event-age-in-seconds 3600 \
  --destination-config '{
    "OnSuccess": {
      "Destination": "arn:aws:sqs:ap-northeast-1:123456789012:success-queue"
    },
    "OnFailure": {
      "Destination": "arn:aws:sqs:ap-northeast-1:123456789012:failure-queue"
    }
  }'

宛先として使えるサービス

OnSuccess(成功時)の宛先:
  ✅ SQS キュー
  ✅ SNS トピック
  ✅ Lambda 関数(別のLambdaを呼び出す)
  ✅ EventBridge イベントバス

OnFailure(失敗時)の宛先:
  ✅ SQS キュー
  ✅ SNS トピック
  ✅ Lambda 関数
  ✅ EventBridge イベントバス

宛先 vs DLQ の違い

DLQ(Dead Letter Queue):
  → 失敗時のみ(OnFailureのみ)
  → 元のイベントのみ保存(メタデータなし)
  → SQS または SNS のみ対応
  → 関数バージョン/エイリアスレベルで設定

宛先(Destinations):
  → 成功・失敗の両方に設定可能
  → 詳細なコンテキスト情報を含む(関数ARN、応答コード、実行結果等)
  → SQS/SNS/Lambda/EventBridgeに対応
  → より柔軟なルーティング
  
推奨: 新規設計では宛先(Destinations)を使う

宛先レコードの例

// OnFailure 宛先に送られるレコード
{
  "version": "1.0",
  "timestamp": "2026-04-08T10:00:00.000Z",
  "requestContext": {
    "requestId": "xxxx-xxxx-xxxx",
    "functionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:my-function",
    "condition": "RetriesExhausted",
    "approximateInvokeCount": 3
  },
  "requestPayload": {
    "Records": [...]
  },
  "responseContext": {
    "statusCode": 200,
    "executedVersion": "$LATEST",
    "functionError": "Unhandled"
  },
  "responsePayload": {
    "errorMessage": "Connection timeout",
    "errorType": "TimeoutError"
  }
}

失敗ハンドリングのパターン

パターン1: シンプルなDLQ監視
  Lambda失敗 → DLQ(SQS)
  → CloudWatchアラーム(DLQメッセージ数 > 0で通知)
  → 手動調査・リドライブ

パターン2: 宛先 + 自動アラート
  Lambda失敗 → OnFailure宛先(SNSトピック)
  → SNS → メール/Slack通知
  → SNS → Lambda(自動修復処理)

パターン3: 宛先 + EventBridge
  Lambda失敗 → OnFailure宛先(EventBridgeバス)
  → EventBridgeルール → Step Functions(ワークフロー実行)
  → EventBridgeルール → 別Lambda(補完処理)
# Lambda内でのエラーハンドリングと構造化エラー出力
import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.ERROR)

def lambda_handler(event, context):
    try:
        result = process_event(event)
        return {"statusCode": 200, "body": result}
    except Exception as e:
        logger.error({
            "errorType": type(e).__name__,
            "errorMessage": str(e),
            "requestId": context.aws_request_id,
            "event": event
        })
        raise  # 再スローしてLambdaの再試行・宛先機能を発動させる

イベントソースマッピングでの失敗ハンドリング

SQS/Kinesis/DynamoDB Streamsトリガーは同期呼び出しのため、Destinationsではなく以下を使う。

# SQSイベントソースマッピングの失敗設定
aws lambda create-event-source-mapping \
  --function-name my-function \
  --event-source-arn arn:aws:sqs:ap-northeast-1:123456789012:my-queue \
  --batch-size 10 \
  --function-response-types ReportBatchItemFailures \
  --destination-config '{
    "OnFailure": {
      "Destination": "arn:aws:sqs:ap-northeast-1:123456789012:my-queue-dlq"
    }
  }'

試験頻出ポイント

シナリオ回答
Lambda失敗時に詳細な情報を保存宛先(Destinations)のOnFailure
Lambda成功時に次の処理を呼び出す宛先(Destinations)のOnSuccess
非同期呼び出しの最大再試行回数デフォルト2回(合計3回の実行)
DLQと宛先の違い宛先は成功/失敗両方に対応、詳細情報を含む
イベントエイジの上限デフォルト6時間(最大21600秒)

まとめ

Lambda宛先(Destinations)はDLQの上位互換で、成功・失敗の両方に対応し詳細なコンテキスト情報を含む。新規設計では宛先を使い、最大試行回数とイベントエイジを適切に設定することが重要だ。