6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

サーバーレスアプリケーションでエラーに対処する (AWS Step Functions + AWS Lambda)

Last updated at Posted at 2018-11-30

Lambda 関数は、以下のような場合、処理に失敗することがあります。
・処理されない例外
・タイムアウトよりも長い時間実行された場合
・メモリ不足が発生した場合
このような場合、AWS Step Functions を使用して、エラーを適切に処理するサーバーレスワークフローを設計し、実行します。


###1.API に模擬コールを行う Lambda 関数を作成する###
この Lambda 関数では、イベントパラメータで入力として指定されたエラーコードに応じて例外を発生させ、架空の API からの応答をシミュレートします。

Lambdaを開き、「一から作成」で、Lambda 関数を以下のように設定し、「関数の作成」をクリック。
・名前:「適当な名前」
・ランタイム:「Python 3.6」
・ロール:「lambda_basic_execution」
image.png

[関数コード]を以下のように編集し、「保存」してください。
ここでは、API の模擬応答を実行する簡単な Lambda 関数の作成です。

class TooManyRequestsException(Exception): pass
class ServerUnavailableException(Exception): pass
class UnknownException(Exception): pass

def lambda_handler(event, context):
    statuscode = event["statuscode"]    
    if statuscode == "429":
        raise TooManyRequestsException('429 Too Many Requests')
    elif statuscode == "503":
        raise ServerUnavailableException('503 Server Unavailable')
    elif statuscode == "200":
        return '200 OK'
    else:
        raise UnknownException('Unknown error')

画面右上の ARN を書き留めておいてください。

###2.IAM ロールを作成する###

[このロールを使用するサービス]で「Step Functions」を選択してIAM ロールを作成しておいてください。

###3.Step Functions のステートマシンを作成する###

Step Functions を開き、「一から作成」します。
[名前]:適当な名前
[ステートマシンの定義]:以下のコードを入力します。
なお、Resource 部分は自分のものにかえてください。

{
  "Comment": "An example of using retry and catch to handle API responses",
  "StartAt": "Call API",
  "States": {
    "Call API": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
      "Next" : "OK",
      "Comment": "Catch a 429 (Too many requests) API exception, and resubmit the failed request in a rate-limiting fashion.",
      "Retry" : [ {
        "ErrorEquals": [ "TooManyRequestsException" ],
        "IntervalSeconds": 1,
        "MaxAttempts": 2
      } ],
      "Catch": [ 
        {
          "ErrorEquals": ["TooManyRequestsException"],
          "Next": "Wait and Try Later"
        }, {
          "ErrorEquals": ["ServerUnavailableException"],
          "Next": "Server Unavailable"
        }, {
          "ErrorEquals": ["States.ALL"],
          "Next": "Catch All"
        }
      ]
    },
    "Wait and Try Later": {
      "Type": "Wait",
      "Seconds" : 1,
      "Next" : "Change to 200"
    },
    "Server Unavailable": {
      "Type": "Fail",
      "Error":"ServerUnavailable",
      "Cause": "The server is currently unable to handle the request."
    },
    "Catch All": {
      "Type": "Fail",
      "Cause": "Unknown error!",
      "Error": "An error of unknown type occurred"
    },
    "Change to 200": {
      "Type": "Pass",
      "Result": {"statuscode" :"200"} ,
      "Next": "Call API"
    },
    "OK": {
      "Type": "Pass",
      "Result": "The request has succeeded.",
      "End": true
    }
  }
}

「既存のIAMロールを作成する」を選択し、2.で作成したIAMロールを紐づけます。
image.png

###4.エラー処理ワークフローをテストする###

「実行の開始」をする。
image.png

「新しい実行」 画面でユーザーが API の部分を担当し、模擬 API によって返してもらいたいエラーコードを指定します。
以下のコードを入力し、「実行の開始」をクリックします。

{
    "statuscode": "200"
}

「入力」 をクリックし、↑ が入力されていることを確認します。
「出力」 をクリックすると、ステータスコード 200 がワークフローによって API コールの成功として解釈されたことを確認できます。
image.png

[ビジュアルワークフロー] で、各実行の実行パスを確認できます。
"Call API" をクリックすると [入力] フィールドと [出力] フィールドが展開されます。
この状態によって、指定した入力を使用して模擬 API Lambda 関数が正常に呼び出され、その Lambda 関数の出力 "200 OK" が取得されたことを確認できます。
image.png

"OK" をクリックします。
[ステップの詳細] で、前のステップの出力 (Call API) が、このステップへの入力として渡されたことを確認できます。
image.png

###5.ステートマシンの実行を検証する###

今回は以下の入力を指定して 「実行の開始」 をクリック。

{
    "statuscode": "503"
}

この実行は失敗すると想定しているため、驚かないでください。 以下のプロセスが実行されたことがわかります。
image.png

429 例外のシミュレーションを行います。
「実行の開始」をクリックし、以下を入力します。

{
    "statuscode": "429"
}

ワークフローの再試行動作を確認していきましょう。

[実行イベント履歴] でFunctions によって MockAPILambda 関数がもう 2 回呼び出されていることを確認します。
この呼び出しは両方とも失敗しています。この時点では、ワークフローは、API が一時的に応答していないだけと考えて、Wait and Try Later 状態 (右側の画像に表示) に遷移します。
image.png

次に、Wait 状態によって強制的に応答コードが 200 に変更されるため、ワークフローは実行を正常に完了できます。
image.png

今度は、ステートマシンによって処理されないランダムな API 応答を指定してみましょう。

{
    "statuscode": "999"
}

失敗ともちろんなる。
image.png

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?