使用 Lambda 函数继续新的执行 - Amazon Step Functions
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 Lambda 函数继续新的执行

您可以创建一个使用 Lambda 函数的状态机,用于在当前执行终止之前启动新的执行。使用这种方法在新执行中继续您正在进行的工作,可以凭借状态机将大型作业拆分成较小的工作流程,或使您的状态机无限期运行。

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

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

状态 用途

ConfigureCount

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

Iterator

引用 Task Lambda 函数的 Iterator 状态。

IsCountReached

Choice 状态,使用 Iterator 函数的布尔值来决定状态机是否应继续示例工作,或移动到 ShouldRestart 状态。

ExampleWork

Pass 状态,表示 Task 状态将在实际实施中执行工作。

ShouldRestart

Choice 状态,使用 executionCount 值来决定是否应结束一个执行并启动另一个,或直接结束。

Restart

Task 状态,使用 Lambda 函数来启动状态机的新执行。与 Iterator 函数一样,此函数的计数也会递减。Restart 状态将计数的递减值传递给新执行的输入。

先决条件

在开始之前,请仔细阅读创建使用 Lambda 的 Step Functions 状态机教程,确保您熟悉如何同时使用 Lambda 和 Step Functions。

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

注意

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

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

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

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

创建迭代 Lambda 函数

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

  2. 创建函数页面上,选择从头开始创作

  3. 基本信息部分中,配置您的 Lambda 函数:

    1. 对于 Function name(函数名称),请输入 Iterator

    2. 对于运行时系统,选择 Node.js 16.x

    3. 保留页面上的所有默认选项,然后选择创建函数

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

      arn:aws:lambda:us-east-1:123456789012:function:Iterator
  4. 将以下 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 }) }

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

  5. 选择部署,部署代码。

测试迭代 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. 选择 创建

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

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

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

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

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

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

  2. 创建函数页面上,选择从头开始创作

  3. 基本信息部分中,配置您的 Lambda 函数:

    1. 对于 Function name(函数名称),请输入 Restart

    2. 对于运行时系统,选择 Node.js 16.x

  4. 保留页面上的所有默认选项,然后选择创建函数

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

    arn:aws:lambda:us-east-1:123456789012:function:Iterator
  5. 将以下 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); }); }
  6. 选择部署,部署代码。

第 3 步:创建状态机

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

例 ShouldRestart 选择状态

下面的示例显示 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" },
创建状态机
  1. 打开 Step Functions 控制台,然后选择创建状态机

  2. 选择模板对话框中,选择空白

  3. 选择选择。这将在设计模式中打开 Workflow Studio。

  4. 在本教程中,您将在代码编辑器中编写状态机的 Amazon States Language (ASL) 定义。要执行此操作,请选择代码

  5. 删除现有的样板代码并粘贴以下代码。请记住将此代码中的 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 } } }
  6. 为状态机指定一个名称。为此,请选择默认状态机名称旁边的编辑图标MyStateMachine。然后,找到状态机配置,在状态机名称框中指定一个名称。

    对于本教程,请输入名称 ContinueAsNew

  7. (可选)在状态机配置中,指定其他工作流设置,例如状态机类型及其执行角色。

    在本教程中,请保留状态机设置中的所有默认选项。

    如果您之前为状态机创建了具有正确权限的 IAM 角色并想使用该角色,请在权限中选择选择现有角色,然后从列表中选择一个角色。或者选择输入角色 ARN,然后为该 IAM 角色的 ARN 获取该角色。

  8. 确认角色创建对话框中,选择确认继续。

    您也可以选择查看角色设置,返回至状态机配置

    注意

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

  9. 将这个状态机的 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 以规定启动新执行的次数。

  1. ContinueAsNew页面上,选择开始执行

    随即显示启动执行对话框。

  2. 启动执行对话框中,执行以下操作:

    1. (可选)要识别您的执行,您可以在名称框中为其指定一个名称。默认情况下,Step Functions 会自动生成一个唯一的执行名称。

      注意

      Step Functions 允许您为状态机、执行和活动创建名称,以及包含非 ASCII 字符的标签。这些非 ASCII 名称不适用于亚马逊。 CloudWatch为确保您可以跟踪 CloudWatch 指标,请选择仅使用 ASCII 字符的名称。

    2. 输入框中,输入以下 JSON 输入,运行您的工作流。

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

    4. 选择启动执行

    5. Step Functions 控制台会将您引导到一个以您的执行 ID 为标题的页面。该页面被称为执行详细信息页面。在此页面上,您可以随着执行的进展或者在执行完成后查看执行结果。

      要查看执行结果,请在图表视图上选择各个状态,然后在步骤详细信息窗格中选择各个选项卡,分别查看每个状态的详细信息,包括输入、输出和定义。有关可在执行详细信息页面上查看的执行信息的详细信息,请参阅“执行详细信息”页面 – 界面概述

      图标视图显示四个执行中的第一个。在完成之前,它将传递 Restart 状态并启动新执行。

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

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

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

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

      所有执行全部完成。