はじめに
こんにちは。技術4課の河野です。 今回は、AWS Step Functions(以下「SFN」) で AWS Lambda(以下「Lambda」) がタイムアウトした場合に、再試行する方法について紹介します。 AWS公式ドキュメントにも、事前にエラー処理をステートマシンに定義することがベストプラティクスと記載されています。 もちろん、タイムアウト以外にも想定されるエラーはきちんと定義しておきましょう。
目次
- 作成するものについて
- 手順
- Lambda 作成
- SFN 作成
- 動作確認
- まとめ
作成するものについて
今回は、以下のような単純なステートマシンを定義します。 ステートマシンが Lambda を呼び出し、呼び出した Lambda がタイムアウトした際に再試行します。
今回はServerlss Framework というサーバレスアプリケーションの構築管理ができる 無料のオープンソースを使用して構築及びデプロイを行います。 インストール方法などの各種準備については割愛します。詳細については、弊社過去記事を参考にしていただければ幸いです。
- サーバーレスシステム構築のベストプラクティス! Serverless Frameworkをもっと試してみよう! API GatewayとDynamoDB編
- Step FunctionsでLambda延命
手順
Lambda 作成
まずは、10秒間待機させる単純な関数を作成します。
import time def handler(event=None, context=None): # 10秒待機 time.sleep(10) return {}
予め Lambda のタイムアウト時間を5秒に設定することで、タイムアウトエラーを発生させます。
SFN 作成
次に、ステートマシンを定義します。 最初に示したワークフローを作成するには、serverless.yml を下記のように編集します。
service: stepfunctions provider: name: aws runtime: python3.8 stage: dev region: ap-northeast-1 plugins: - serverless - serverless-step-functions package: include: handler.py exclude: - node_modules/** - .serverless/** functions: timeoutSample: handler: handler.handler name: ${self:provider.stage}-timeout-sample timeout: 5 stepFunctions: stateMachines: myStepFUnctions: name: myStepfunctions definition: StartAt: executeFunction States: executeFunction: Type: Task Resource: Fn::GetAtt: [timeoutSample,Arn] TimeoutSeconds: 60 ResultPath: '$' Retry: - ErrorEquals: - 'Lambda.Unknown' IntervalSeconds: 1 MaxAttempts: 2 End: True
再試行は、上記のRetry
フィールドで定義しています。
設定している各パラメータについて解説します。
ErrorEquals
キャッチするエラーを指定します。ステートマシンの実行結果と指定したエラーが一致した場合に再試行されます。
メモリ不足や関数タイムアウトなどの Lambda で処理されないエラーは、Lambda.Unknown
、 States.ALL
または、States.TaskFailed
で一致できます。
その他の Lambda に関するエラーはAWS Lambda Developer Guideを参考にしてキャッチするエラーを指定することができます。
IntervalSeconds
初回の再試行までの時間です。2回目以降は、BackoffRate
の設定値によって増加します。
MaxAttempts
再試行の最大回数になります。最大回数を超えると、ステートマシーンでエラーとなり処理が終了します。
それでは、デプロイして実際の動作を確認していきましょう。
動作確認
2回の再試行後、ステートマシンが終了していることを確認できました。
まとめ
今回は、StepFunctions で再試行する方法について紹介しました。
- エラー処理はステートマシンに事前に定義しておく
- 再試行はRetryフィールドで定義できる
ErrorEquals
にキャッチするエラーを指定する
最後まで読んでいただきありがとうございました。