延迟数小时调用lambda函数



我正试图找出在5小时后调用aws lambda函数的最佳方法。我有另一个lambda函数,它会发出多个检索作业来从aws冰川中抓取项目,我需要一个解决方案,在检索到每个项目后,对它们运行另一个lambda函数,这大约需要5个小时。我在考虑使用sns,但想知道是否还有其他方法。任何输入都是值得赞赏的。

2022年11月14日更新:

AWS发布了EventBridge的一个新功能,名为EventBridge Scheduler,它可以让您安排一次性或重复的操作,如调用Lambda函数。在上面的问题中,调度以延迟数小时调用Lambda函数,CLI调用可能如下所示:

aws scheduler create-schedule --name lambda-templated --expression 'at(2022-11-20T13:00:00)' 
--target '{"RoleArn": "ROLE_ARN", "Arn":"FUNCTION_ARN", "Input": "{ "Payload": "TEST_PAYLOAD" }" }' 
--flexible-time-window '{ "Mode": "OFF"}'

在这种情况下,expression是在2022年11月20日下午1点UTC+0调用Lambda函数的一次性时间表。

target参数需要特定的格式,具体取决于要执行的操作。Lambda Invoke的模板目标文档中描述了上述格式。

旧答案(在某些情况下仍然适用):

除了使用CloudWatch,在您的情况下,另一种有趣的方法是使用AWS步骤函数:

  1. 通过设置固定周期使用等待状态(如果您向状态机提供输入数据,则使用动态周期):

    {
    "Comment": "An example of the Amazon States Language using wait states",
    "StartAt": "WaitState",
    "States": {
    "WaitState": {
    "Type": "Wait",
    "Seconds": 10,
    "Next": "MyLambda"
    },
    "MyLambda": {
    "Type": "Task",
    "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
    "End": true
    }
    }
    }
    
  2. 或者,您可以在任务状态中使用一个单独的Lambda函数,并结合一个选择状态,在循环中检查其他函数是否应该运行:

    {
    "Comment": "A state machine that submits a Job to AWS Batch and monitors the Job until it completes.",
    "StartAt": "Wait X Seconds",
    "States": {
    "Wait X Seconds": {
    "Type": "Wait",
    "SecondsPath": "$.wait_time",
    "Next": "Get Job Status"
    },
    "Get Job Status": {
    "Type": "Task",
    "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:CheckJob",
    "Next": "Job Complete?"
    },
    "Job Complete?": {
    "Type": "Choice",
    "Choices": [
    {
    "Variable": "$.status",
    "StringEquals": "RUNNING",
    "Next": "Wait X Seconds"
    },
    {
    "Variable": "$.status",
    "StringEquals": "SUCCEEDED",
    "Next": "Do Job"
    }
    ],
    "Default": "Wait X Seconds"
    },
    "Do Job": {
    "Type": "Task",
    "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:DoJob",
    "End": true
    }
    } 
    }
    

我觉得基于cloudwatch和step函数的解决方案不能很好地扩展,而且它们在代码方面相当繁重。

我建议创建两个SQS队列。一个是等待队列,另一个是执行队列。

等待队列:将执行队列设置为等待队列的死信队列。将"默认可见性超时"设置为要等待运行lambda的时间(最多12小时)。将最大接收数设置为1。创建一个使用SQS消息并返回错误的Lambda。将等待队列作为触发器添加到此lambda。

exports.handler =  async function(event, context) {
throw new Error('Go back to the waiting queue and wait');
}

执行队列:将执行队列作为触发器添加到Lambda(您想要调度的)中。

然后,要调度lambda,只需向等待队列发布一条消息。

消息将进入等待队列,在那里它将被错误输出lambda消耗掉。它将一直停留在等待队列中,直到它的可见性超时,然后它将被推到死信执行队列中,由您计划的lambda提取。

理想的方法是使用CloudWatch事件调度Lambda函数。请在这里查看相同的更多详细信息

最新更新