探索 Step Functions 中的服务集成模式
对于服务集成,您可以指定各种集成模式来控制状态机与 Amazon 集成服务的交互方式:
-
请求响应 - 调用服务,Step Functions 将在获得 HTTP 响应后立即进入下一个状态。
-
运行作业 (.sync) - 调用服务,并让 Step Functions 等待作业完成。
-
等待具有任务令牌的回调 - 使用任务令牌调用服务并让 Step Functions 等待,直到该令牌与有效载荷一起返回。
上述每种服务集成模式都受控于在任务定义的 "Resource" 字段中创建 URI 的方式。
Step Functions 中的 ASL 资源值是一个唯一的名称(URI),它符合 ARN 格式,但通常无法识别账户中的实际资源。前缀“arn:aws:states:”设置 Step Functions 用于集成的命名空间。该值的 ::: 部分表示空白 region 和 account-id 字段是不必要的,因为两者都是从运行工作流的区域和账户推断出来的。
与 Amazon Lambda 的传统集成是唯一的例外,其中资源值指定实际的 Lambda 函数资源。Step Functions 控制台将显示这些旧版资源,但除非您选择直接编辑 ASL 代码,否则将无法在当今的图形用户界面中创建或编辑此类资源。
集成模式支持
标准工作流程和快速工作流程支持相同的集成,但支持的集成模式不同。
-
标准工作流程支持请求响应 集成。某些服务支持运行任务 (.sync) 或等待回调 (.waitForTaskToken),在某些情况下同时支持这两者。有关详细信息,请参阅以下优化集成表。
-
快速工作流程仅支持请求响应 集成。
为协助在两种类型之间做出选择,请参阅在 Step Functions 中选择工作流程类型。
Step Functions 中的 Amazon SDK 集成
| 集成 服务 | 请求响应 | 运行任务:.sync | 等待回调:.waitForTaskToken |
|---|---|---|---|
| 超过两百项服务 | 标准和快速 | 不支持 | Standard |
Step Functions 中的优化集成
| 集成 服务 | 请求响应 | 运行任务:.sync | 等待回调:.waitForTaskToken |
|---|---|---|---|
| Amazon API Gateway | 标准和快速 | 不支持 | Standard |
| Amazon Athena | 标准和快速 | Standard | 不支持 |
| Amazon Batch | 标准和快速 | Standard | 不支持 |
| Amazon Bedrock | 标准和快速 | Standard | Standard |
| Amazon CodeBuild | 标准和快速 | Standard | 不支持 |
| Amazon DynamoDB | 标准和快速 | 不支持 | 不支持 |
| Amazon ECS/Fargate | 标准和快速 | Standard | Standard |
| Amazon EKS | 标准和快速 | Standard | Standard |
| Amazon EMR | 标准和快速 | Standard | 不支持 |
| Amazon EMR on EKS | 标准和快速 | Standard | 不支持 |
| Amazon EMR Serverless | 标准和快速 | Standard | 不支持 |
| Amazon EventBridge | 标准和快速 | 不支持 | Standard |
| Amazon Glue | 标准和快速 | Standard | 不支持 |
| Amazon Glue DataBrew | 标准和快速 | Standard | 不支持 |
| Amazon Lambda | 标准和快速 | 不支持 | Standard |
| AWS Elemental MediaConvert | 标准和快速 | Standard | 不支持 |
| Amazon SageMaker AI | 标准和快速 | Standard | 不支持 |
| Amazon SNS | 标准和快速 | 不支持 | Standard |
| Amazon SQS | 标准和快速 | 不支持 | Standard |
| Amazon Step Functions | 标准和快速 | Standard | Standard |
请求响应
在任务状态的 "Resource" 字符串中指定服务,并且只提供资源时,Step Functions 将等待 HTTP 响应,然后进入下一个状态。Step Functions 不会等待作业完成。
以下示例显示了如何发布 Amazon SNS 主题。
"Send message to SNS": {
"Type":"Task",
"Resource":"arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn":"arn:aws:sns:region:123456789012:myTopic",
"Message":"Hello from Step Functions!"
},
"Next":"NEXT_STATE"
}
此示例引用了 Amazon SNS 的 Publish API。调用 Publish API 后,工作流进入下一状态
提示
要部署使用请求响应服务集成模式的示例工作流,请参阅本指南入门教程中的集成服务,或《The Amazon Step Functions Workshop》中的 Request Response 模块
运行作业 (.sync)
对于集成服务(如 Amazon Batch 和 Amazon ECS),Step Functions 可以等到请求完成后再进入下一个状态。要让 Step Functions 等待,请使用在资源 URI 之后附加的 .sync 后缀,在任务状态定义中指定 "Resource" 字段。
例如,当提交 Amazon Batch 作业时,在状态机定义中使用 "Resource" 字段,如本示例所示。
"Manage Batch task": {
"Type": "Task",
"Resource": "arn:aws:states:::batch:submitJob.sync",
"Parameters": {
"JobDefinition": "arn:aws:batch:us-east-2:123456789012:job-definition/testJobDefinition",
"JobName": "testJob",
"JobQueue": "arn:aws:batch:us-east-2:123456789012:job-queue/testQueue"
},
"Next": "NEXT_STATE"
}
将 .sync 部分附加到资源 Amazon 资源名称 (ARN) 上意味着 Step Functions 会等待作业完成。在调用 Amazon Batch submitJob 后,工作流会暂停。作业完成后,Step Functions 将进入下一状态。有关更多信息,请参阅 Amazon Batch 示例项目:使用 Amazon Batch 和 Amazon SNS 管理批处理任务。
如果使用此 (.sync) 服务集成模式的任务中止,并且 Step Functions 无法取消该任务,则集成服务可能会向您收取额外费用。在以下情况下,任务可能被中止:
-
状态机执行被停止。
-
并行状态的另一个分支因未捕获的错误而失败。
-
Map 状态的一次迭代失败并出现未捕获的错误。
Step Functions 将尽力尝试取消任务。例如,如果 Step Functions states:startExecution.sync 任务中止,它将调用 Step Functions StopExecution API 操作。但是,Step Functions 可能无法取消该任务。原因包括但不限于:
-
您的 IAM 执行角色没有权限进行相应的 API 调用。
-
发生临时服务中断。
当您使用 .sync 服务集成模式时,Step Functions 会使用轮询来监控任务的状态,并且会消耗分配的配额和事件。对于同一账户内的 .sync 调用,Step Functions 会使用 EventBridge 事件并轮询 Task 状态中指定的 API。对于跨账户的 .sync 调用,Step Functions 仅使用轮询。例如,对于 states:StartExecution.sync,Step Functions 会对 DescribeExecution API 执行轮询,并使用您指定的配额。
提示
要部署使用 .sync 集成模式的示例工作流,请参阅《The Amazon Step Functions Workshop》中的 Run a Job (.sync)
要查看等待作业完成的集成服务支持的列表 (.sync),请参阅 将服务与 Step Functions 集成。
注意
使用 .sync 或 .waitForTaskToken 模式的服务集成需要额外的 IAM 权限。有关更多信息,请参阅 Step Functions 如何为集成服务生成 IAM 策略。
在某些情况下,您可能希望 Step Functions 在任务完全完成之前继续工作流。实现的方法与等待具有任务令牌的回调服务集成模式相同。为此,请将任务令牌传递给作业,然后使用 SendTaskSuccess 或 SendTaskFailure API 调用将其返回。Step Functions 会使用您在该调用中提供的数据来完成任务、停止监控作业并继续工作流。
等待具有任务令牌的回调
回调任务提供了一种暂停工作流程,直到返回任务令牌的方法。任务可能需要等待人员批准、与第三方集成或调用旧式系统。对于此类任务,您可以暂停 Step Functions,直到工作流执行达到一年的服务限额(参阅与状态限制相关的配额),然后等待外部流程或工作流完成。针对这些情况,Step Functions 允许您将任务令牌传递给 Amazon 开发工具包服务集成以及某些优化服务集成。任务将会暂停,直到它通过 SendTaskSuccess 或 SendTaskFailure 调用接收到该任务令牌。
如果使用回调任务令牌的 Task 状态超时,则会生成一个新的随机令牌。您可以从上下文对象访问任务令牌。
注意
任务令牌必须包含至少 1 个字符,并且不能超过 1024 个字符。
要将 .waitForTaskToken 与 Amazon 开发工具包集成一起使用,您使用的 API 必须具有用于放置任务令牌的参数字段。
注意
您必须从同一 Amazon 账户中的主体处传递任务令牌。如果您使用其他 Amazon 账户的主体发送令牌,则令牌将无法使用。
提示
要部署使用回调任务令牌集成模式的示例工作流程,请参阅 The Amazon Step Functions Workshop 中的 Callback with Task Token
要查看支持等待任务令牌的集成服务的列表 (.waitForTaskToken),请参阅 将服务与 Step Functions 集成。
任务令牌示例
在此示例中,Step Functions 工作流需要与外部微服务集成,才能在批准工作流中执行信用检查。Step Functions 会发布一条 Amazon SQS 消息,该消息中包含任务令牌。外部系统与 Amazon SQS 集成,并将消息从队列中拉出。完成后,它将返回结果和原始任务令牌。然后 Step Functions 继续其工作流。
引用 Amazon SQS 的任务定义的 "Resource" 字段包括附加到末尾的 .waitForTaskToken。
"Send message to SQS": {
"Type": "Task",
"Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken",
"Parameters": {
"QueueUrl": "https://sqs.us-east-2.amazonaws.com/123456789012/myQueue",
"MessageBody": {
"Message": "Hello from Step Functions!",
"TaskToken.$": "$$.Task.Token"
}
},
"Next": "NEXT_STATE"
}
这会指示 Step Functions 暂停并等待任务令牌。使用 .waitForTaskToken 指定资源时,可以使用特殊路径名称 ("Parameters") 在状态定义的 $$.Task.Token 字段中访问任务令牌。初始 $$. 指定访问上下文对象的路径,并在正在运行的执行中获取当前任务的任务令牌。
完成后,外部服务会调用 SendTaskSuccess 或 SendTaskFailure,其中包含 taskToken。只有这样,工作流程才会继续进入下一个状态。
注意
要避免在流程无法与 SendTaskSuccess 或 SendTaskFailure 一起发送任务令牌时无限期地等待,请参阅为等待任务配置检测信号超时。
从上下文对象获取令牌
上下文对象是一个内部 JSON 对象,其中包含有关执行的信息。与状态输入一样,可以在执行期间使用来自 "Parameters" 字段的路径访问它。从任务定义中访问时,它包含有关特定执行的信息(包括任务令牌)。
{
"Execution": {
"Id": "arn:aws:states:region:account-id:execution:stateMachineName:executionName",
"Input": {
"key": "value"
},
"Name": "executionName",
"RoleArn": "arn:aws:iam::account-id:role...",
"StartTime": "2019-03-26T20:14:13.192Z"
},
"State": {
"EnteredTime": "2019-03-26T20:14:13.192Z",
"Name": "Test",
"RetryCount": 3
},
"StateMachine": {
"Id": "arn:aws:states:region:account-id:stateMachine:stateMachineName",
"Name": "name"
},
"Task": {
"Token": "h7XRiCdLtd/83p1E0dMccoxlzFhglsdkzpK9mBVKZsp7d9yrT1W"
}
}
您可以使用任务定义的 "Parameters" 字段内的特殊路径来访问任务令牌。要访问输入或上下文对象,首先通过将 .$ 附加到参数名称来指定参数将是路径。以下内容指定 "Parameters" 规范中输入和上下文对象的节点。
"Parameters": {
"Input.$": "$",
"TaskToken.$": "$$.Task.Token"
},
在这两种情况下,将 .$ 添加到参数名称会告知 Step Functions 期望一个路径。在第一种情况下,"$" 是一个路径,其中包含整个输入。在第二种情况下,$$. 指定路径将访问上下文对象,$$.Task.Token 将参数设置为正在运行的执行的上下文对象中的任务令牌的值。
在 Amazon SQS 示例中,"Resource" 字段中的 .waitForTaskToken 告诉 Step Functions 等待任务令牌返回。"TaskToken.$":
"$$.Task.Token" 参数将该令牌作为 Amazon SQS 消息的一部分传递。
"Send message to SQS": {
"Type": "Task",
"Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken",
"Parameters": {
"QueueUrl": "https://sqs.us-east-2.amazonaws.com/123456789012/myQueue",
"MessageBody": {
"Message": "Hello from Step Functions!",
"TaskToken.$": "$$.Task.Token"
}
},
"Next": "NEXT_STATE"
}
有关上下文对象的更多信息,请参阅本指南在 Step Functions 中从上下文对象访问执行数据 部分中的处理输入和输出。
为等待任务配置检测信号超时
等待任务令牌的任务将等到执行达到一年服务配额(请参阅 与状态限制相关的配额)。要避免执行卡顿,您可以在状态机定义中配置检测信号超时间隔。使用 HeartbeatSeconds 字段指定超时间隔。
{
"StartAt": "Push to SQS",
"States": {
"Push to SQS": {
"Type": "Task",
"Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken",
"HeartbeatSeconds": 600,
"Parameters": {
"MessageBody": { "myTaskToken.$": "$$.Task.Token" },
"QueueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/push-based-queue"
},
"ResultPath": "$.SQS",
"End": true
}
}
}
在此状态机定义中,任务将消息推送到 Amazon SQS 并等待外部进程使用提供的任务令牌进行回调。"HeartbeatSeconds":
600 字段将检测信号超时间隔为 10 分钟。该任务将等待任务令牌通过以下 API 操作之一返回:
如果等待任务在该 10 分钟内未收到有效的任务令牌,则任务失败并显示 States.Timeout 错误名称。
有关更多信息,请参阅回调任务示例项目:使用 Amazon SQS、Amazon SNS 和 Lambda 创建回调模式示例。