我正试图找出在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步骤函数:
通过设置固定周期使用等待状态(如果您向状态机提供输入数据,则使用动态周期):
{ "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 } } }
或者,您可以在任务状态中使用一个单独的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函数。请在这里查看相同的更多详细信息