AWS Step Functions
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

使用新执行继续工作

本教程向您展示如何利用 Lambda 函数创建状态机,该函数可启动新执行,并在该新执行中继续工作。

AWS Step Functions 旨在运行持续时间和步骤数量有限的工作流程。执行的持续时间限制为一年,事件数量最多为 25000 个(请参阅限制)。

但是,您可以创建状态机,在允许当前执行终止之前,使用 AWS Lambda 函数来启动新执行。这样您就可以凭借状态机将大型任务拆分成较小的工作流程,或使您的状态机无限期运行。

本教程背后的理念是,使用外部 Lambda 函数修改您的工作流程,详情请见使用 Lambda 迭代循环教程。您将使用相同的 Lambda 函数 (Iterator) 将循环迭代特定次数。此外,您将创建另一个 Lambda 函数来启动工作流程的新执行,并在每次启动新执行之后将计数减一。在输入中设置执行次数后,此状态机将结束并重新开始执行达指定的次数。


      工作流程概述

您将要创建的状态机可实施以下状态。

State 目的
ConfigureCount

配置了 countindexstep 值的 Pass 状态,Iterator Lambda 函数使用这些值来分步执行工作的迭代。

Iterator

引用 Iterator Lambda 函数的 Task 状态。

IsCountReached Choice 状态,使用 Iterator 函数的布尔值来决定状态机是否应继续示例工作,或移动到 ShouldRestart 选择状态。
ExampleWork 在此示例中,ExampleWorkPass 状态,表示 Task 状态将在实际实施中执行工作。
ShouldRestart Choice 状态,使用 executionCount 值来决定是否应结束一个执行并启动另一个,或直接结束。
Restart Task 状态,使用 Lambda 函数来启动状态机的新执行。与 Iterator 函数一样,此函数的计数也会递减。它会将值传递到新执行的输入。

先决条件

在开始之前,请浏览创建 Lambda 状态机教程以确保您创建了初始 IAM 角色,并且熟悉如何结合使用 Lambda 和 Step Functions。

步骤 1:创建迭代计数的 Iterate Lambda 函数

注意

如果您已完成使用 Lambda 迭代循环教程,可以跳过此步骤并使用该 Lambda 函数。

本节和使用 Lambda 迭代循环教程展示了如何使用 Lambda 函数来跟踪计数,以便您跟踪状态机中循环的迭代次数。

以下 Lambda 函数接收 countindexstep 的输入值。它返回这些值及更新的 index 和一个名为 continue 的布尔值。如果 index 小于 count,Lambda 函数将 continue 设置为 true

然后,状态机实施 Choice 状态:在 continuetrue 时执行一些应用程序逻辑,或在 continuefalse 时继续执行 ShouldRestart

创建 Iterate Lambda 函数

  1. 打开 Lambda 控制台,然后选择创建函数

  2. 创建函数部分中,选择从头开始创作

  3. Author with code snippets (使用代码段创作) 部分中,配置 Lambda 函数,如下所示:

    1. 对于名称,输入 Iterator

    2. 对于 Runtime,选择 Node.js 6.10

    3. 对于 Role,选择 Choose an existing role

    4. 对于现有角色,选择您在创建 Lambda 状态机教程中创建的 Lambda 角色。

      注意

      如果您创建的 IAM 角色未显示在列表中,该角色可能仍需要几分钟才能传播到 Lambda。

    5. 选择 Create function

      创建 Lambda 函数后,记下函数位于页面右上角的 Amazon 资源名称 (ARN),例如:

      arn:aws-cn:lambda:us-east-1:123456789012:function:Iterator
  4. 将以下 Lambda 函数代码复制到 Lambda 控制台中的迭代器 页面的配置部分中。

    exports.iterator = function iterator (event, context, callback) { let index = event.iterator.index let step = event.iterator.step let count = event.iterator.count index += step callback(null, { index, step, count, continue: index < count }) }

    此代码接受 countindexstep 的输入值。它将 index 递增 step 的值,并返回这些值及布尔值 continue。如果 index 小于 countcontinue 的值为 true

  5. 选择 Save

测试 Iterate Lambda 函数

使用数字值运行 Iterate 函数,查看它的工作情况。您可以为模拟迭代的 Lambda 函数提供输入值,以查看使用特定输入值得到的输出。

测试 Lambda 函数

  1. 配置测试事件对话框中,选择创建新测试事件,然后键入 TestIterator 作为事件名称

  2. 使用以下内容替换示例数据。

    { "Comment": "Test my Iterator function", "iterator": { "count": 10, "index": 5, "step": 1 } }

    这些值模拟在迭代期间来自状态机的内容。Lambda 函数递增索引并将 continue 返回为 true。当索引不小于 count 时,它会将 continue 返回为 false。在此测试中,索引已增加到 5。结果应将 index 增加到 6,并将 continue 设置为 true

  3. 选择 Create

  4. 在 Lambda 控制台中的迭代器 页面上,确保列出了 TestIterator,然后选择测试

    测试结果将显示在页面顶部。选择详细信息并查看结果。

    { "index": 6, "step": 1, "count": 10, "continue": true }

    注意

    如果在此测试中将 index 设置为 9,则 index 增加到 10continuefalse

步骤 2:创建 Restart Lambda 函数,启动新的 Step Functions 执行

  1. 打开 Lambda 控制台,然后选择创建函数

  2. Author with code snippets (使用代码段创作) 部分中,配置 Lambda 函数,如下所示:

    1. 对于名称,输入 Restart

    2. 对于 Runtime,选择 Node.js 6.10

    3. 对于 Role,选择 Choose an existing role

    4. 现有角色下,选择包含您之前创建的 IAM 策略的角色。

    5. 选择 Create function

      创建 Lambda 函数后,记下函数位于页面右上角的 Amazon 资源名称 (ARN),例如:

      arn:aws-cn:lambda:us-east-1:123456789012:function:Restart
  3. 将以下 Lambda 函数代码复制到 Lambda 控制台中的重启 页面的配置部分中。

    以下代码可将执行次数的计数递减,并启动状态机的新执行,包括已递减的值。

    var aws = require('aws-sdk'); var sfn = new aws.StepFunctions(); exports.restart = function(event, context, callback) { let StateMachineArn = event.restart.StateMachineArn; event.restart.executionCount -= 1; event = JSON.stringify(event); let params = { input: event, stateMachineArn: StateMachineArn }; sfn.startExecution(params, function(err, data) { if (err) callback(err); else callback(null,event); }); }
  4. 选择 Save

步骤 3:创建状态机

现在,您已创建了两个 Lambda 函数,可以创建状态机。在此状态机中,ShouldRestartRestart 状态表示如何将工作拆分为多个执行。

例 ShouldRestart Choice 状态

状态机的这个部分展示 ShouldRestart Choice 状态。此状态决定是否应重新开始执行。

"ShouldRestart": { "Type": "Choice", "Choices": [ { "Variable": "$.restart.executionCount", "NumericGreaterThan": 1, "Next": "Restart" } ],

初始执行的输入中包含 $.restart.executionCount 值。每次调用 Restart 函数后它会减 1,并置入每个后续执行的输入中。

例 重启任务状态

状态机的这个部分展示 Restart Task 状态。此状态使用您之前创建的 Lambda 函数重新启动执行,并递减计数来跟踪剩余的执行启动次数。

"Restart": { "Type": "Task", "Resource": "arn:aws-cn:lambda:us-east-1:123456789012:function:Restart", "Next": "Done" },
  1. 在 Step Functions 控制台中,选择 Create a state machine (创建状态机)

  2. 选择 Author with code snippets (使用代码段创作),然后输入 ContinueAsNew 作为您的状态机名称。

  3. 将以下内容粘贴到 Code 窗格。

    例 ContinueAsNew 状态机

    { "Comment": "Continue-as-new State Machine Example", "StartAt": "ConfigureCount", "States": { "ConfigureCount": { "Type": "Pass", "Result": { "count": 100, "index": -1, "step": 1 }, "ResultPath": "$.iterator", "Next": "Iterator" }, "Iterator": { "Type": "Task", "Resource": "arn:aws-cn:lambda:us-east-1:123456789012:function:Iterator", "ResultPath": "$.iterator", "Next": "IsCountReached" }, "IsCountReached": { "Type": "Choice", "Choices": [ { "Variable": "$.iterator.continue", "BooleanEquals": true, "Next": "ExampleWork" } ], "Default": "ShouldRestart" }, "ExampleWork": { "Comment": "Your application logic, to run a specific number of times", "Type": "Pass", "Result": { "success": true }, "ResultPath": "$.result", "Next": "Iterator" }, "ShouldRestart": { "Type": "Choice", "Choices": [ { "Variable": "$.restart.executionCount", "NumericGreaterThan": 0, "Next": "Restart" } ], "Default": "Done" }, "Restart": { "Type": "Task", "Resource": "arn:aws-cn:lambda:us-east-1:123456789012:function:Restart", "Next": "Done" }, "Done": { "Type": "Pass", "End": true } } }
  4. 更新 RestartIterator 状态中的 Resource 字符串,引用您之前创建的各 Lambda 函数。

  5. 选择 Next (下一步)

  6. 创建或输入 IAM 角色。

    • 要为 Step Functions 创建新的 IAM 角色,请选择 Create an IAM role for me (为我创建 IAM 角色),然后输入角色的 Name (名称)

    • 如果您使用您的状态机的正确权限之前已创建 IAM 角色,请选择 Choose an existing IAM role (选择现有 IAM 角色)。从下拉列表中选择一个角色,或者提供该角色的 ARN。

    注意

    如果您删除了 Step Functions 创建的 IAM 角色,Step Functions 在以后无法重新创建它。同样,如果您修改角色 (例如,通过在 IAM 策略中从委托人删除 Step Functions),Step Functions 在以后无法还原其原始设置。

  7. 选择 Create state machine (创建状态机)

注意

保存此状态机的 Amazon 资源名称 (ARN)。

步骤 4:更新 IAM 策略

要确保您的 Lambda 函数有启动 Step Functions 新执行的权限,请为您的 Restart Lambda 函数所用的 IAM 角色附加内联策略。有关更多信息,请参阅 IAM 用户指南 中的嵌入内联策略

{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "states:StartExecution" ], "Resource": "*" } ] }

注意

您可以更新上个示例的 "Resource": "*" 行,引用 ContinueAsNew 状态机的 ARN。这会限制该策略,使它只能启动特定状态机的执行。

步骤 5:运行执行

要开始执行,请在输入中包含状态机的 ARN,并提供 executionCount 以规定启动新执行的次数。

  1. ContinueAsNew 页面上,选择 New execution (新执行)。

  2. New execution (新执行) 页面的 Input (输入) 部分,输入 Test1 作为执行名称。然后在 Input (输入) 中输入以下内容。

    { "restart": { "StateMachineArn": "arn:aws-cn:states:us-east-1:123456789012:stateMachine:ContinueAsNew", "executionCount": 4 } }
  3. 使用您的 ContinueAsNew 状态机的 ARN 更新 StateMachineArn 字段。

  4. 选择 Start Execution (开始执行)

Visual Workflow (可视工作流程) 图表显示四个执行中的第一个。在完成之前,它将传递 Restart 状态并启动新执行。


        四个执行中的第一个执行。

此执行完成后,您可以查看下一个正在运行的执行。选择顶部的 ContinueAsNew 链接,查看执行列表。您应该可以看到最近关闭的执行,以及 Restart Lambda 函数启动的正在进行的执行。


        一个执行完成,下一个执行相继运行。

所有执行全部完成后,您应在列表中看到四个成功完成的执行。启动的首个执行显示您所选的名称,后续执行的名称是自动生成的。


        所有执行全部完成。