本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
在 Step Functions 中使用 Lambda 函数继续新的执行
提示
以下方法使用 Lambda 函数来启动新的工作流程执行。我们建议使用 Step Functions Task 状态来启动新的工作流程执行。在以下教程中查看操作方法:使用 Step Functions API 继续长时间运行的工作流程(建议)。
您可以创建一个使用 Lambda 函数的状态机,用于在当前执行终止之前启动新的执行。通过这种方法在新的执行中继续正在进行的工作,可以将大型任务分解为较小的工作流程,或者无限期地运行工作流程。
本教程背后的理念是,使用外部 Lambda 函数修改您的工作流程,详情请见在 Step Functions 中使用 Lambda 函数迭代循环教程。您将使用相同的 Lambda 函数 (Iterator
) 将循环迭代特定次数。此外,您将创建另一个 Lambda 函数来启动工作流程的新执行,并在每次启动新执行之后将计数减一。在输入中设置执行次数后,此状态机将结束并重新开始执行达指定的次数。
您将要创建的状态机可实施以下状态。
状态 | 用途 |
---|---|
|
配置了 |
|
引用 |
|
Choice 状态,使用 Iterator 函数的布尔值来决定状态机是否应继续示例工作,或移动到 ShouldRestart 状态。 |
|
Pass 状态,表示 Task 状态将在实际实施中执行工作。 |
|
Choice 状态,使用 executionCount 值来决定是否应结束一个执行并启动另一个,或直接结束。 |
|
Task 状态,使用 Lambda 函数来启动状态机的新执行。与 Iterator 函数一样,此函数的计数也会递减。Restart 状态将计数的递减值传递给新执行的输入。 |
先决条件
在开始之前,请仔细阅读创建使用 Lambda 的 Step Functions 状态机教程,确保您熟悉如何同时使用 Lambda 和 Step Functions。
第 1 步:创建迭代计数的 Lambda 函数
注意
如果您已完成在 Step Functions 中使用 Lambda 函数迭代循环教程,可以跳过此步骤并使用该 Lambda 函数。
本节和在 Step Functions 中使用 Lambda 函数迭代循环教程展示了如何使用 Lambda 函数来跟踪计数,例如,状态机中循环的迭代次数。
以下 Lambda 函数接收 count
、index
和 step
的输入值。它返回这些值及更新的 index
和一个名为 continue
的布尔值。如果 continue
小于 true
,Lambda 函数将 index
设置为 count
。
然后,状态机实施 Choice
状态:在 continue
为 true
时执行一些应用程序逻辑,或在 continue
为 false
时继续执行 ShouldRestart
。
创建迭代 Lambda 函数
-
打开 Lambda 控制台
,然后选择创建函数。 -
在创建函数页面上,选择从头开始创作。
-
在基本信息部分中,配置您的 Lambda 函数:
-
对于函数名称,请输入
Iterator
。 -
对于运行时系统,选择 Node.js 16.x。
-
保留页面上的所有默认选项,然后选择创建函数。
创建 Lambda 函数后,记下函数位于页面右上角的 Amazon 资源名称 (ARN),例如:
arn:aws:lambda:us-east-1:123456789012:function:Iterator
-
-
将以下 Lambda 函数代码复制到 Lambda 控制台
Iterator
页面的代码源部分中。exports.handler = function iterator (event, context, callback) { let index = event.iterator.index; let step = event.iterator.step; let count = event.iterator.count; index = index + step; callback(null, { index, step, count, continue: index < count }) }
此代码接受
count
、index
和step
的输入值。它将index
递增step
的值,并返回这些值及布尔值continue
。如果index
小于count
,continue
的值为true
。 -
选择部署,部署代码。
测试迭代 Lambda 函数
使用数字值运行 Iterate
函数,查看它的工作情况。您可以为模拟迭代的 Lambda 函数提供输入值,以查看使用特定输入值得到的输出。
测试 Lambda 函数
-
在配置测试事件对话框中,选择创建新测试事件,然后键入
TestIterator
作为事件名称。 -
使用以下内容替换示例数据。
{ "Comment": "Test my Iterator function", "iterator": { "count": 10, "index": 5, "step": 1 } }
这些值模拟在迭代期间来自状态机的内容。Lambda 函数递增索引并将
continue
返回为true
。当索引不小于count
时,它会将continue
返回为false
。在此测试中,索引已增加到5
。结果应将index
增加到6
,并将continue
设置为true
。 -
选择创建。
-
在 Lambda 控制台中的
Iterator
页面上,确保列出了 TestIterator,然后选择测试。测试结果将显示在页面顶部。选择详细信息并查看结果。
{ "index": 6, "step": 1, "count": 10, "continue": true }
注意
如果在此测试中将
index
设置为9
,则index
增加到10
,continue
为false
。
第 2 步:创建一个 Restart Lambda 函数,启动新的 Step Functions 执行
-
打开 Lambda 控制台
,然后选择创建函数。 -
在创建函数页面上,选择从头开始创作。
-
在基本信息部分中,配置您的 Lambda 函数:
-
对于函数名称,请输入
Restart
。 -
对于运行时系统,选择 Node.js 16.x。
-
-
保留页面上的所有默认选项,然后选择创建函数。
创建 Lambda 函数后,记下函数位于页面右上角的 Amazon 资源名称 (ARN),例如:
arn:aws:lambda:us-east-1:123456789012:function:Iterator
-
将以下 Lambda 函数代码复制到 Lambda 控制台
Restart
页面的代码源部分中。以下代码可将执行次数的计数递减,并启动状态机的新执行,包括已递减的值。
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); }); }
-
选择部署,部署代码。
第 3 步:创建状态机
现在,您已创建了两个 Lambda 函数,可以创建状态机。在此状态机中,ShouldRestart
和 Restart
状态表示如何将工作拆分为多个执行。
例 ShouldRestart Choice 状态
下面的示例显示 ShouldRestart
Choice
状态。此状态决定是否应重新开始执行。
"ShouldRestart": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.restart.executionCount",
"NumericGreaterThan": 1,
"Next": "Restart"
}
],
初始执行的输入中包含 $.restart.executionCount
值。每次调用 Restart
函数后它会减 1,并置入每个后续执行的输入中。
例 Restart Task 状态
下面的示例显示 Restart
Task
状态。此状态使用您之前创建的 Lambda 函数重新启动执行,并递减计数来跟踪剩余的执行启动次数。
"Restart": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:Restart
",
"Next": "Done"
},
创建状态机
-
打开 Step Functions 控制台
,然后选择创建状态机。 在 选择模板对话框中,选择空白。
选择选择,以便在设计模式下打开工作流程工作室。
-
在本教程中,您将在代码编辑器中编写状态机的 Amazon States Language (ASL) 定义。要执行此操作,请选择代码。
-
删除现有的样板代码并粘贴以下代码。请记住将此代码中的 ARN 替换为您创建的 Lambda 函数的 ARN。
{ "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: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:lambda:us-east-1:123456789012:function:Restart
", "Next": "Done" }, "Done": { "Type": "Pass", "End": true } } } -
为状态机指定一个名称。要执行此操作,请选择默认状态机名称 MyStateMachine 旁边的编辑图标。然后,找到状态机配置,在状态机名称框中指定一个名称。
对于本教程,请输入名称
ContinueAsNew
。 -
(可选)在状态机配置中,指定其他工作流设置,例如状态机类型及其执行角色。
在本教程中,请保留状态机设置中的所有默认选项。
如果您之前为状态机创建了具有正确权限的 IAM 角色并想使用该角色,请在权限中选择选择现有角色,然后从列表中选择一个角色。或者选择输入角色 ARN,然后为该 IAM 角色的 ARN 获取该角色。
-
在确认角色创建对话框中,选择确认继续。
您也可以选择查看角色设置,返回至状态机配置。
注意
如果您删除了 Step Functions 创建的 IAM 角色,Step Functions 在以后无法重新创建该角色。同样,如果您修改了该角色(例如,通过在 IAM 策略中从主体中删除 Step Functions),Step Functions 在以后也无法还原其原始设置。
-
将这个状态机的 Amazon 资源名称 (ARN) 保存在一个文本文件中。您需要提供 ARN,同时向 Lambda 函数提供权限才能启动新的 Step Functions 执行。
第 4 步:更新 IAM 策略
要确保您的 Lambda 函数有启动 Step Functions 新执行的权限,请为您的 Restart
Lambda 函数所用的 IAM 角色附加内联策略。有关更多信息,请参阅《IAM 用户指南》中的嵌入内联策略。
注意
您可以更新上个示例的 Resource
行,引用 ContinueAsNew
状态机的 ARN。这会限制该策略,使它只能启动特定状态机的执行。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "states:StartExecution" ], "Resource": "
arn:aws:states:us-east-2:123456789012stateMachine:ContinueAsNew
" } ] }
第 5 步:运行状态机
要开始执行,请在输入中包含状态机的 ARN,并提供 executionCount
以规定启动新执行的次数。
-
在 ContinueAsNew 页面上,选择启动执行。
随即显示启动执行对话框。
-
在启动执行对话框中,执行以下操作:
-
(可选)输入自定义执行名称,以便覆盖生成的默认执行名称。
非 ASCII 名称和日志记录
Step Functions 对于状态机、执行、活动和标签接受包含非 ASCII 字符的名称。由于此类字符不适用于 Amazon CloudWatch,因此我们建议您仅使用 ASCII 字符,这样您就可以在 CloudWatch 中跟踪指标。
-
在输入框中,输入以下 JSON 输入,运行您的工作流。
{ "restart": { "StateMachineArn": "
arn:aws:states:us-east-1:123456789012:stateMachine:ContinueAsNew
", "executionCount":4
} } -
使用您的
ContinueAsNew
状态机的 ARN 更新StateMachineArn
字段。 -
选择启动执行。
-
Step Functions 控制台会将您引导到一个以您的执行 ID 为标题的页面。该页面被称为执行详细信息页面。在此页面上,您可以随着执行的进展或者在执行完成后查看执行结果。
要查看执行结果,请在图表视图上选择各个状态,然后在步骤详细信息窗格中选择各个选项卡,分别查看每个状态的详细信息,包括输入、输出和定义。有关可在执行详细信息页面上查看的执行信息的详细信息,请参阅执行详细信息概览。
图标视图显示四个执行中的第一个。在完成之前,它将传递
Restart
状态并启动新执行。此执行完成后,您可以查看下一个正在运行的执行。选择顶部的 ContinueAsNew 链接,查看执行列表。您应该可以看到最近关闭的执行,以及
Restart
Lambda 函数启动的正在进行的执行。所有执行全部完成后,您应在列表中看到四个成功完成的执行。启动的首个执行显示您所选的名称,后续执行的名称是自动生成的。
-