Amazon EventBridge Schedulerのデッドレターキュー(DLQ)を使ってみた

2022.11.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Amazon EventBridge Scheduler はデッドレターキュー(DLQ)に対応しており、ターゲットを呼び出せなかったイベントを、DLQにルーティングできます。

EventBridge RuleもDLQに対応していますが、EventBridge Schedulerはより詳細なイベント情報・メトリクスを取得できるようになっています。

この機能について解説します。

Amazon EventBridge SchedulerのDLQについて

Amazon EventBridge Schedulerがスケジュール通りにターゲットを呼び出せなかった場合、Amazon SQSキューにデッドレターイベントを送信します。ユーザーは、このデッドレターメッセージから、呼び出し失敗の原因がわかります。

DLQ は SQS で管理

AWS の他のデッドレターキューと同じく、Amazon EventBridge Scheduler の DLQはAmazon SQS で管理されているため、DLQ 用の SQS キューを作成します。スタンダードキューにのみ対応し、FIFOキューには対応していません。

また、EventBridge Schedulerがターゲットを呼び出すための実行ロールに、SQS キューイング用の権限も追加します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            既存ポリシー
        },
        {
            "Action": [
                "sqs:SendMessage"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:sqs:<REGION>:<ACCOUNT-ID>:<QUEUE-NAME>"
        }
    ]
}

リトライポリシー

ターゲットの呼び出しに失敗すると、リトライポリシーに従い、スケージュールを再実行します。

リトライポリシーは MaximumEventAgeInSecondsMaximumRetryAttempts の2つのパラメーターで構成されます。

パラメーター MaximumEventAgeInSeconds MaximumRetryAttempts
コンソールフィールド名 Maximum age of event Retry attempts
意味 リトライを試みる期間(秒) リトライを試みる回数
デフォルト 24時間 185回
最小 60 0
最大 86400 185

リトライ間隔は exponential backoff でコントロールします。

MaximumEventAgeInSeconds または MaximumRetryAttempts のどちらかの閾値を超えると、 DLQ に送信されます。

エラー発生時には必ず再試行するわけではありません。

次の EventBridge Rule のドキュメントに記載されているように、パーミッション不足やターゲットが存在しないといった、永続的な問題が起きているときは、リトライせずに即座に DLQ へイベント送信します。EventBridge Scheduler もこの仕様を踏襲していると思われます。

Event errors are handled in different ways. Some events are dropped or sent to a DLQ without any retry attempts. For example, for errors that result from missing permissions to a target, or a target resource that no longer exists, all retry attempts fail until an action is taken to resolve the underlying issue. Rather than retrying, EventBridge sends these events directly to the DLQ, if you have one.

https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-rule-dlq.html

デッドレターイベントを発生

実際に呼び出しエラーを発生させ、デッドレターイベントを確認します。

スケジュールの実行ロールから、ターゲットを呼び出すためのポリシーを外して動作確認しました。

イベントメッセージを確認

本文(body)には、ターゲットの呼び出し情報があります。

{
  "Input": "{}",
  "Name": "68d43b39655f8226",
  "StateMachineArn": "arn:aws:states:eu-central-1:123456789012:stateMachine:MyStateMachine"
}

属性(messageAttributes)には、呼び出しの失敗理由が記録されています。

Name Type Value
ERROR_CODE String AccessDeniedException
ERROR_MESSAGE String User: arn:aws:sts::123456789012:assumed-role/Amazon_EventBridge_Scheduler_XXX/612YYY is not authorized to perform: states:StartExecution on resource: arn:aws:states:eu-central-1:123456789012:stateMachine:MyStateMachine because no identity-based policy allows the states:StartExecution action
EXECUTION_ID String 68d43b39655f8226
IS_PAYLOAD_TRUNCATED String false
RETRY_ATTEMPTS String 0
SCHEDULED_TIME String 2022-11-14T15:18:42Z
SCHEDULE_ARN String arn:aws:scheduler:eu-central-1:123456789012:schedule/default/test-schedule
TARGET_ARN String arn:aws:states:eu-central-1:123456789012:stateMachine:MyStateMachine

ERROR_CODE から AccessDeniedException が発生したことがわかり、ERROR_MESSAGE から Execution Role の権限不足であるとわかります。 ポリシーの不備という永続的な問題でエラーが起きているため、再試行していません(RETRY_ATTEMPTS の値は 0)。

参考までに、同様のエラーを起こしたときの EventBridge Rule の DLQ 属性は以下の通りです。

Name Type Value
ERROR_CODE String NO_PERMISSIONS
ERROR_MESSAGE String User: arn:aws:sts::123456789012:assumed-role/Amazon_EventBridge_Invoke_Step_Functions_666517840/82bd09e7f98836e9bc49b801f9de231f is not authorized to perform: states:StartExecution on resource: arn:aws:states:eu-central-1:123456789012:stateMachine:MyStateMachine because no identity-based policy allows the states:StartExecution action (Service: AWSStepFunctions; Status Code: 400; Error Code: AccessDeniedException; Request ID: 3e21b4a1-5a97-4d1e-956b-69f946232d60; Proxy: null)
RULE_ARN String arn:aws:events:eu-central-1:123456789012:rule/my-schedule-rule
TARGET_ARN String arn:aws:states:eu-central-1:123456789012:stateMachine:MyStateMachine

EventBridge Scheduler の DLQ メッセージ は SCHEDULED_TIME など情報量が増えていますね。

DLQ 系 CloudWatch メトリクス

EventBridge Scheduler の DLQ には 以下のメトリクスが存在します。

Namespace Scheduler Metric Rule Metric Unit Description
AWS/Scheduler InvocationsSentToDeadLetterCount InvocationsSentToDlq Count Emitted for every successful delivery to a schedule's DLQ. Use this to determine when events are sent to a DLQ, then check the event delivered to the schedule's DLQ for additional details that help you determine the cause of the failure.
AWS/Scheduler InvocationsFailedToBeSentToDeadLetterCount InvocationsFailedToBeSentToDlq Count Emitted when EventBridge Scheduler cannot deliver an event to the DLQ. Use these two metrics to determine the reason why EventBridge Scheduler is unable to send an event to the DLQ, and modify your DLQ configuration to resolve the issue.
AWS/Scheduler InvocationsFailedToBeSentToDeadLetterCount_<error_code> N.A. Count
AWS/Scheduler InvocationsSentToDeadLetterCount_Truncated_MessageSizeExceeded N.A. Count Emitted when the payload of the event sent to the DLQ exceeds the maximum size allowed by Amazon SQS, and EventBridge Scheduler truncates the payload you specify in the Input attribute of a schedule.

参考情報として、EventBridge Rules の同等のメトリクスも併記しています。

InvocationsFailedToBeSentToDeadLetterCount_<error_code> は InvocationsFailedToBeSentToDeadLetterCount をブレイクダウンしたものです。

権限不足の場合は InvocationsFailedToBeSentToDeadLetterCount_AccessDenied、DLQ送信先のSQSキューが存在しない場合は InvocationsFailedToBeSentToDeadLetterCount_AWS.SimpleQueueService.NonExistentQueue というように、エラー内容に応じたメトリクスが割り当てられます。

実際のメトリクスは以下の通りです。

最後に

EventBridge Schedulerのデッドレターキュー(DLQ)を使ってみました。

EventBridge SchedulerのDLQの設定は EventBridge Rule と同じですが、Scheduler は Rule よりも DLQ メッセージや CloudWatch Metrics の情報量が増えています。

EventBridge Ruleはイベントとスケジュールに対応するために、汎用的な作りになっているのに対し、EventBridge Schedulerはスケジュールに特化しているため、詳細な情報を提供しやすいのが原因と思われます。

EventBridge 利用時には、DLQ を設定し、エラー系 CloudWatch Metrics を監視し、呼び出し失敗時には即座に気づけるようにしましょう。

それでは。

参考