【问题标题】:Does AWS Step Functions have a timeout feature?AWS Step Functions 是否具有超时功能?
【发布时间】:2020-02-27 23:28:15
【问题描述】:

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

【问题讨论】:

  • 你显然没有明白我在问什么,你的链接没有帮助。我想要整个状态机/ emr 集群作为一个整体的超时功能,not 像链接中的每个单独任务。我还希望超时长度由用户输入参数管理,不是在您的链接中的任务中的硬编码值。
  • docs.aws.amazon.com/step-functions/latest/dg/… TimeoutSeconds (可选) - 这是您可以定义整台机器超时的方式,因此您可以在启动前生成模板并设置整个超时
  • 谢谢。我有这个使用硬编码的超时值,但是您知道是否可以通过输入参数设置超时值,例如使用输入参数"timeout": 600 开始执行并使用"TimeoutSeconds": "$.timeout"? 设置状态机我我不确定如何执行此操作,因为 "TimeoutSeconds" 似乎只接受硬编码的整数值。
  • 另外,我将使用状态机运行 EMR 集群,您知道是否可以在超时发生时将状态机指向特定任务,而不仅仅是让状态机停止它在哪里?我想让它指向一个任务,我可以编写一个 lambda 函数或其他东西来在状态机超时时终止正在运行的 EMR 集群,而不是状态机只是停止并让 EMR 集群启动并等待。跨度>

标签: amazon-web-services aws-step-functions


【解决方案1】:

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

当一个分支在 Parallel 状态中失败时,它会中止其他分支中的所有运行状态。幸运的是,您能够在 Parallel State 中捕获这些错误,并将其重定向到另一个状态,具体取决于哪个分支失败。这是我的意思的一个示例(更改 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
    }
 }
}

【讨论】:

  • 在一个非常复杂的状态机上成功使用了这种方法,我有 4 个可能的分支可以停止给定的处理。不幸的是,原生并行没有“任何时候”选项,因为这样可以避免将异常用作控制流。
  • 步进函数现在支持从状态输入路径添加动态超时。请参阅下面@George Novack 的回答。 stackoverflow.com/a/66235388/3450425
【解决方案2】:

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

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

【讨论】:

  • 我认为这是截至 2021 年正确且最新的答案。
【解决方案3】:

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

所以外部应该是:

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

inner 的内容为:

  • 执行 EMR 工作

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 2020-01-29
    • 1970-01-01
    相关资源
    最近更新 更多