【问题标题】:Can you trigger an AWS Lambda on a dynamic timer?您可以在动态计时器上触发 AWS Lambda 吗?
【发布时间】:2017-05-24 07:13:03
【问题描述】:

有没有办法在动态计时器上触发 AWS Lambda?目前,我正在利用预定事件来触发 lambda,但这是一个设置的计时器。有没有办法动态设置 Lambda 在 Lambda 内触发的时间?

这里的想法是,这个 Lambda 执行特定的检查并执行代码以知道它应该何时运行(因为我只希望这个 lambda 在需要时运行)。我想 1) 确定下一次需要运行的时间,以及 2) 从 Lambda 代码中设置时间。

我看到有很多资源用于触发 Lambda 函数(SNS、Kinesis 等),但我似乎找不到动态启动的好方法。

【问题讨论】:

  • 我没有对此进行任何详细研究,但您能否简单地向您的 Lambda 函数添​​加一些代码来编辑实际触发 Lambda 的 CloudWatch 事件计划?相关:stackoverflow.com/questions/27382009/…

标签: amazon-web-services scheduled-tasks aws-lambda


【解决方案1】:

这可以通过设置 CloudWatch 事件规则来触发您的 Lambda 函数来完成。每次调用 Lambda 函数时,该函数都需要确定其下一次运行时间并适当地修改事件规则。

var AWS = require("aws-sdk");

exports.handler = function(event, context) {
    var cloudwatchevents = new AWS.CloudWatchEvents();
    var intervals = Array(3, 5, 7);
    var nextInterval = intervals[Math.floor(Math.random()*intervals.length)];
    var currentTime = new Date().getTime(); // UTC Time
    var nextTime = dateAdd(currentTime, "minute", nextInterval);
    var nextMinutes = nextTime.getMinutes();
    var nextHours = nextTime.getHours();

    //  =================================
    //  DO YOUR WORK HERE
    //  =================================

    var scheduleExpression = "cron(" + nextMinutes + " " + nextHours + " * * ? *)";
    var params = {
        Name: "YOUR CLOUDWATCH EVENT RULE NAME",
        ScheduleExpression: scheduleExpression
    };
    cloudwatchevents.putRule(params, function(err, data) {
        if (err) {
            console.log(err, err.stack);  
        }
        else {
            console.log(data);
        }
    })
};

var dateAdd = function(date, interval, units) {
    var ret = new Date(date); // don't change original date
    switch(interval.toLowerCase()) {
        case 'year'   :  ret.setFullYear(ret.getFullYear() + units);  break;
        case 'quarter':  ret.setMonth(ret.getMonth() + 3*units);  break;
        case 'month'  :  ret.setMonth(ret.getMonth() + units);  break;
        case 'week'   :  ret.setDate(ret.getDate() + 7*units);  break;
        case 'day'    :  ret.setDate(ret.getDate() + units);  break;
        case 'hour'   :  ret.setTime(ret.getTime() + units*3600000);  break;
        case 'minute' :  ret.setTime(ret.getTime() + units*60000);  break;
        case 'second' :  ret.setTime(ret.getTime() + units*1000);  break;
        default       :  ret = undefined;  break;
    }
    return ret;
}

您应该能够将我的随机决定与您自己的调度逻辑交换,并插入您需要的任何工作来代替我的评论。

您需要在我的 sn-p 中将您的事件规则名称替换为“YOUR CLOUDWATCH EVENT RULE NAME”。

博客的好问题:AWS Lambda Functions That Dynamically Schedule Their Next Runtime

【讨论】:

  • 这基本上就是我们所做的。只需修改 CloudWatch 计时器,使其以下次我需要它启动时的速率运行。唯一的问题是精度不低于一分钟。不幸的是,计划的事件不允许有几秒钟的 cron 作业。但这暂时就足够了。
  • 在这种情况下我们不需要指定目标吗?
  • 答案中的博文链接不存在了
【解决方案2】:

现在无需使用步进函数进行轮询即可完成此操作。您可以在AWS 上找到更多信息,但基本上您将为使用Wait 状态和TimestampPath 字段的步进函数定义一个状态机。你的状态机可能最终看起来像

{
  "SartAt": "WaitState",
  "States": {
    "WaitState":     {
      "Type":          "Wait",
      "TimestampPath": "$.timestamp",
      "Next":          "ExecuteLambda"
    },
    "ExecuteLambda": {
      "Type":          "Task",
      "Resource":      "lambda-arn",
      "End":           true,
      "Retry":         [
        { ... },
        ...
      ]
  }
}

假设您使用的是 Node,然后您可以使用以下代码调用 step 函数:

const AWS = require('aws-sdk');

const stepFunctions = new AWS.StepFunctions();

await stepFunctions.startExecution({
  stateMachineArn: process.env.STATE_MACHINE_ARN,
  name:            "unique-name",
  input:           JSON.stringify({
    timestamp: (new Date(/*Date you want to start execution*/)).toISOString(),
    // Any extra context you want to pass to the step function.
  }),
}).promise();

【讨论】:

    【解决方案3】:

    您可以创建 CloudWatch 规则以在特定时间运行。 CloudWatch 规则可以定期运行,也可以使用类似 cron 的语法来指定单个运行时间。不过,您可能需要稍后清理它们。

    【讨论】:

    • 能否在 lambda 中动态设置 cloudwatch 规则?
    【解决方案4】:

    您可以按计划继续执行 lambda,但在 DynamoDB 或 S3 等数据存储中保留一个值,该值告诉 lambda 何时应该下一次运行。

    lambda 将继续定期执行,但您可以控制它何时实际执行其预期用途。这里有计费方面的考虑(lambda 将继续在后台消耗最少的资源),但希望事情不会太失控。可能比尝试从同一个 lambda 中管理触发器更简单。

    【讨论】:

    • 问题是我需要控制 lambda 何时运行,而不是 lambda 上的指定代码何时运行。我确实保留了让我知道下一次运行时间的数据,但必要的是 lambda 运行时间是可配置的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 2012-01-12
    • 2022-01-07
    • 2020-05-17
    • 2020-04-11
    • 1970-01-01
    相关资源
    最近更新 更多