Step Functionsのエラー処理・通知、リトライを考える
ステートのリトライ
リトライを設定できるステートはTask
、Parallel
、Map
ステートです。これらはRetry
フィールドを持つことができます。
Retry
のErrorEquals
フィールドには、States.ALL
などの公式ドキュメント記載の「エラー名」のほか、Lambda.ClientExecutionTimeoutException
やZeroDivisionError
といった値も指定することができます。
とりあえずエラーを全部拾う場合はStates.ALL
を使用します。
参考:
Lambda関数呼び出しのリトライのベストプラクティス
リトライによって解決する可能性の高い、Lambdaの一時的なエラーに対してリトライを設定するようにします。
マネジメントコンソールでLambda: Invoke
ステートを作成すると、自動的に以下のデフォルト設定が入るようになっています。
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2
}
]
ステートのエラー処理
Task
、Parallel
、Map
ステートではエラーをキャッチして別のステートに遷移させることができます。設定はCatch
フィールドで行います。
リトライ設定がある場合は、すべてのリトライに失敗した後でキャッチが実行されます。
Catch
のErrorEquals
フィールドの考え方はRetry
と同じです。
参考:Fallback 状態
Parallel/Mapステートのエラー処理
Parallel
やMap
ステートで、一部のブランチ/イテレーションが失敗してもすべての処理を完了させたい場合には、内部でエラーをキャッチする必要があります。
参考:Parallel task error handling in Step Functions - DEV Community
ただし、その場合はステートマシン全体が成功で完了するため、エラーがあったことに気づけないおそれがあります。その対策として、内部のエラーキャッチ後に通知の仕組みを入れておくか、Parallel
やMap
ステートが終わった後でエラーを検知してステートマシンを失敗させるような処理を入れておく必要があります。
参考:Parallel/Map内でエラー処理するけどマシン全体は失敗させる
ステートマシンのエラー通知
ステートマシン全体のエラー通知をざっくりやるには、主に以下のパターンが考えられます。
- CloudWatchメトリクス→CloudWatchアラーム→SNSトピック
- EventBridge→User Notifications
CloudWatchメトリクスを使用する場合は、AWS/States
名前空間のExecutionsFailed
とExecutionsTimedOut
メトリクスを拾ってアラームを発報します。
参考:Amazon CloudWatch を使用した Step Functions メトリクスのモニタリング
EventBridgeを使用する場合は、Step Functions Execution Status Change
イベントタイプで、FAILED
とTIMED_OUT
ステータスを拾って通知します。User Notificationsの通知が実行履歴に辿りやすくて良い感じです。
参考:
- AWS Step FunctionsのエラーをAWS User Notificationsを使って簡単に通知してみた(メール・Slack) | DevelopersIO
- EventBridge による Step Functions イベント配信の自動化
明示的なタイムアウト設定を検討する
ステートマシン全体および各ステートで、必要に応じてタイムアウト時間の設定を検討します。例えば、いくら長くても終わっているはずの時間があるならば、想定外の問題を発見できるようにタイムアウト時間を設定しておくと良いと思います。ステートマシン(標準ワークフロー)のデフォルトのタイムアウトは1年、Task
ステートは1,000日超であるため、最悪の場合実行がスタックしたまま長期間気づかない可能性があります。
最大実行時間
1 年
Step Functions サービスクォータ
TimeoutSeconds (オプション)
... デフォルト値は 99999999 です。
タスクワークフローの状態
参考:タイムアウトを使用して Step Functions ワークフロー実行が停止しないようにする
クォータを考慮する
何かが大きかったり多かったりする場合は、クォータを考慮しましょう。例えば、ペイロードサイズは256kB、実行あたりの履歴は25,000件です。
参考:
Discussion