【问题标题】:Simplified wait on Serverless AWS step function无服务器 AWS 步进函数的简化等待
【发布时间】:2020-04-06 19:30:06
【问题描述】:

我已经通过 Serverless 编写了 AWS Step 函数。逻辑如下所示

1. Execute Job
2. Get job status 
3. Check if job succeeded 
4. If not succeded wait for 60 seconds 

目前,我已经编写了如下定义的阶跃函数

...
stepFunctions: 
  stateMachines: 
    myStateMachine: 
       definition:
         states: 
           ...
           Execute Job: 
             ... 
           Get Job Status: 
             Type: Task 
             Next: Is Job Succeeded?
             # This job check if job is succeeded or not and sets a variable 
             # job_succeeded = true
           Is Job Succeeded?
             Type: Choice
             Choices:
             - Variable: "$.job_succeded"
               BooleanEquals: true
               Next: Next Lambda Function  
             Default: Wait for job
           Wait for job:
             Type: Wait
             Seconds: 60
             Next: Get Job Status
           Next Lambda Function: 
              ...
           ...

这非常有效!

但问题是,我必须为每个异步执行的每个不同作业编写 4 个 lambda,因此如果要完成 4 个此类任务,则将有 4 * 4 个步骤,即 16 个步骤。

这使得 step function 中看起来有很多 lambdas,很难看到实际的流程。

这4个功能可以概括为下面的伪代码

job_succeded = false
while job is not complete:
    job_succeded = get_job_status() 
    if not job_succeded:
        sleep 60 seconds 

可能的解决方案是

stepFunctions: 
  stateMachines: 
    myStateMachine: 
       definition:
         states: 
           ...
           Execute Job: 
             ... 
           Get Job Status: 
             Type: RepeatWhile
             Condition:
             - Variable: "$.job_succeded"
               BooleanEquals: true
               Next: Next Lambda Function
             WaitPeriod: 60 seconds 
             # This job check if job is succeeded or not and sets a variable 
             # job_succeeded = true
           Next Lambda Function: 
              ...
           ...

我知道这不是当前的情况,但这可以简化许多工作流程。 有没有其他方法可以简化这个?

【问题讨论】:

    标签: python-3.x serverless-framework aws-step-functions


    【解决方案1】:

    欢迎使用步进函数!不幸的是,它们在写下来时非常臃肿。我不知道这是否有帮助,但对于像这样简单的事情,我将使用一个 lambda 函数来完成我的所有任务。

    您可以使用附加参数定义步进函数,以告诉您的函数要执行什么

      Task_1:
        Type: Task
        Resource:
          Fn::GetAtt:
            - MyLambdaFunction
            - Arn
        Parameters:
          execute: task_1
        Next: Task_2
    
      Task_2:
        Type: Task
        Resource:
          Fn::GetAtt:
            - MyLambdaFunction
            - Arn
        Parameters:
          execute: task_2
        Next: Task_3 
    

    在您的 lambda 函数中,只需设置一些简单的 if 语句:

      if (event.execute === 'task_1') {
        // run task 1 code
      }
      else if (event.execute === 'task_2') {
        // run task 2 code
      }
    

    我不能完全说出你想在你的问题中做什么,但你也可以从你的 lambda 输出变量,然后触发不同的步骤。您可以为此使用选择状态,例如

          ChoiceState:
            Type: Choice
            Choices:
              # response from lambda should be {executing: 'task_1', status: 'running'}
              - Variable: "$.executing" 
                StringEquals: task_1
              - Variable: "$.status"
                StringEquals: running
              Next: Wait
    
            - And:
              - Variable: "$.executing"
                StringEquals: task_1
              - Variable: "$.status"
                StringEquals: done
              Next: Task_2
    
            - And:
              - Variable: "$.executing"
                StringEquals: task_2
              - Variable: "$.status"
                StringEquals: running
              Next: Wait
    
            - And:
              - Variable: "$.executing"
                StringEquals: task_2
              - Variable: "$.status"
                StringEquals: done
              Next: Completed
    
            Wait:
              Type: Wait
              Seconds: 10
              Next: CheckExecution
    
            Completed:
              Type: Succeed
    
          CheckExecution:
            Type: Task
            Resource:
              Fn::GetAtt:
                - MyLambdaFunction
                - Arn
            Next: ChoiceState
    

    这不是一个完整的解决方案,因为在这里写下来太复杂了。但希望能给你一些额外的想法

    此外,根据您的状态机的运行方式,此方法可在您最大限度地减少 lambda 冷启动时提供性能提升。

    【讨论】:

    • 感谢您的详细解答。我认为您要说的是处理 lambda 中的控制流。但是恕我直言,step 函数是用来处理工作流的,step 函数应该控制工作流而不是代码。
    • lambda 不控制工作流。除非步进函数要求它做任何事情,否则它什么也做不了。 Lambda 只是做它被告知的事情。这对工作流程序列来说是愚蠢的。
    • Lambda 从阶跃函数获取输入,执行某些操作,向阶跃函数发送响应。根据响应,step 函数选择下一步。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    • 2023-03-13
    • 2010-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多