AWS Step Functions 是否具有超时功能?

Does AWS Step Functions have a timeout feature?

现在我有一个 AWS Step Function 来创建、运行 和终止 EMR 集群作业。我想添加一个超时功能来停止作业并终止集群,以防集群卡住或花费太长时间 运行 (例如,将输入变量 "TIMEOUT_AFTER_X_HOURS": 12 传递到状态机以及集群配置,如果它在 12 小时后仍然 运行ning,它将自动停止作业并终止集群)。有谁知道如何做到这一点?

遗憾的是,您不能动态指定状态的超时,但您可以动态地告诉 Wait 状态它应该等待多长时间。话虽如此,我建议您使用具有两个分支和一个 catch 块的并行状态。第一个分支包含等待状态和失败状态(您的超时)。另一个分支包含您的正常状态机逻辑和失败状态。

每当并行状态中的分支失败时,它会中止其他分支中的所有 运行 状态。幸运的是,您能够在并行状态中捕获这些错误,并根据失败的分支将其重定向到另一个状态。这是我的意思的示例(更改 HardCodedInputs 状态中的值以控制哪个分支失败)。

{
"StartAt": "HardCodedInputs",
"States": {
    "HardCodedInputs": {
        "Type": "Pass",
        "Parameters": {
            "WaitBranchInput": {
                "timeout": 5,
                "Comment": "Change the value of timeout"
            },
            "WorkerBranchInput": {
                "SecondsPath": 3,
                "Comment": "SecondsPath is used for testing purposes to simulate how long the worker will run"
            }
        },
        "Next": "Parallel"
    },
    "Parallel": {
        "Type": "Parallel",
        "End": true,
        "Catch": [{
            "ErrorEquals": ["TimeoutExpired"],
            "ResultPath": "$.ParralelStateOutput",
            "Next": "ExecuteIfTimedOut"
        }, {
            "ErrorEquals": ["WorkerSuccess"],
            "ResultPath": "$.ParralelStateOutput",
            "Next": "ExecuteIfWorkerSuccesfull"
        }],
        "Branches": [{
                "StartAt": "DynamicTimeout",
                "States": {
                    "DynamicTimeout": {
                        "Type": "Wait",
                        "InputPath": "$.WaitBranchInput",
                        "SecondsPath": "$.timeout",
                        "Next": "TimeoutExpired"
                    },
                    "TimeoutExpired": {
                        "Type": "Fail",
                        "Cause": "TimeoutExceeded.",
                        "Error": "TimeoutExpired"
                    }
                }
            },
            {
                "StartAt": "WorkerState",
                "States": {
                    "WorkerState": {
                        "Type": "Wait",
                      "InputPath": "$.WorkerBranchInput",
                        "SecondsPath": "$.SecondsPath",
                        "Next": "WorkerSuccessful"
                    },
                    "WorkerSuccessful": {
                        "Type": "Fail",
                        "Cause": "Throw Worker Success Exception",
                        "Error": "WorkerSuccess"
                    }
                }
            }
        ]
    },
    "ExecuteIfTimedOut": {
        "Type": "Pass",
        "End": true
    },
    "ExecuteIfWorkerSuccesfull": {
        "Type": "Pass",
        "End": true
    }
 }
}

我面临类似的问题,我认为解决方案是创建一个管理 EMR 的外部状态机和一个执行工作的内部状态机。

所以外部将是:​​

  • 创建 EMR
  • 根据您的输入变量
  • 在任务上设置 TimeoutSeconds 调用子状态机
  • 终止 EMR

而 inner 的内容为:

  • 执行 EMR 工作

因此,内部机器在成功完成或 TimeoutSeconds 结束后会 return,而在外部机器中,您可以检测到哪个(使用 Catch 状态来捕获States.Timeout 错误)并采取相应措施。

您可以将输入变量的路径(例如原始示例中的 "$.TIMEOUT_AFTER_X_HOURS")传递给任何任务的 TimeoutSecondsPath 参数。这将允许您根据状态机输入或先前步骤的输出动态设置步骤超时。

您可以在此处找到 TimeoutSecondsPath 参数的官方文档:https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-task-state.html