我是Lambda的新手,我正在尝试编写一个函数,该函数每24小时通过SNS发送一封容量不固定的电子邮件。此Lambda功能由IoT规则触发,并且不受24小时限制,收件箱将充满电子邮件。在CloudWatch中,即使email_sent标志等于1,也似乎正在发送电子邮件。这让我觉得我没有正确构造括号和括号吗?有人看到这段代码有什么问题吗?
var email_sent = 0; //Flag to determine if the email has been sent in the last 24 hours
var starttime = new Date(); //Date & time when the script starts running
....
exports.handler = (event, context, callback) => {
console.log('Start time.', starttime);
console.log('Email Sent Flag.', email_sent);
console.log('Received event:', event.my_volume, ' mL Volume'); //Fluid volume
var miliseconds = new Date() - starttime; //Calculate the time that has passed
console.log('Miliseconds.', miliseconds);
console.log(miliseconds/1000 + " Seconds.");
if (miliseconds => 86,400,000) { //Has 24 hours passed?
email_sent = 0; //set the email flag back to zero if the time has passed
}
// create/get topic
if (email_sent == 0) { //if the email flag is not set, setup topic and send the email
createTopic('aws-iot-button-sns-topic', (err, topicArn) => {
if (err) {
return callback(err);
}
console.log(`Publishing to topic ${topicArn}`);
// publish message
const params = {
Message: `The fluid level is low on your system: ${event.my_volume} mL.`,
Subject: `Low Fluid Level Alert - Knight`,
TopicArn: topicArn,
};
// result will go to function callback
SNS.publish(params, callback);
console.log('SNS Published.');
email_sent = 1; // after email is sent, reset the flag
starttime = new Date(); // reset the starttime after the email is sent
}
);
}
};
谢谢
史蒂夫
答案 0 :(得分:0)
所以我认为有两件事应该做的不同。
首先,你有这个:
createTopic('aws-iot-button-sns-topic', (err, topicArn) => {
现在,您的函数正在创建不必要的主题,而无需删除它们,这是一个问题。您应该改为在外部创建SNS主题,并在此处使用Lambda环境变量或对SNS主题arn进行硬编码来对其进行引用。或者,首先检查具有该名称的主题是否已经存在,如果存在,则不要创建它。
第二,Lambda的运行时间不会超过900 seconds (15 minutes),因此无法检查脚本是否已经运行了24小时以上。
您应该做的是创建一个CloudWatch event trigger that runs every 24 hours using cron。这样,您的lambda就会每24小时运行一次(或您配置的任何事件),而在代码中,您只需发送一次消息即可。这样一来,您就不必检查现在几点了或已经发送多少次了,因为您知道事件触发仅发生一次,因此您的消息只发送一次,Lambda会在其后立即终止执行。
Lambdas的本质是它们短暂且无状态,因此请相应地设计您的服务:)
编辑:发表评论后,我会更了解用例...在这种情况下,Lambda由IoT执行,我会亲自将以前的执行时间存储在SSM参数存储或DynamoDB中,然后每当Lambda执行后,我将获取值,检查是否经过24小时,然后发送SNS。您必须执行此操作,因为Lambda不会知道上次执行时间是什么时候(并且请确保仅在成功的SNS发布调用中更新上次执行时间,这样才能确定当天发送了一条消息)
答案 1 :(得分:0)
这是另一种方法...
仅当指标下降到阈值以下时,这只会发送一条消息。也许不需要Lambda。
我不确定如何将IoT指标发送到CloudWatch(我对IoT不太了解)。这可能是相关的:Real-time metrics with AWS IoT Analytics and Amazon CloudWatch | The Internet of Things on AWS – Official Blog
或者,根据测量温度的系统,您可以将指标直接发送到CloudWatch,而不是IoT。
这是Amazon CloudWatch发送到Amazon SNS的示例消息,然后将其发送到SNS主题的所有订阅者:
From: AWS Notifications <no-reply@sns.amazonaws.com>
Date: Mon, 13 May 2019 at 08:03
Subject: ALARM: "Fluid Level alert" in Asia Pacific (Sydney)
You are receiving this email because your Amazon CloudWatch Alarm "Fluid Level alert" in the Asia Pacific (Sydney) region has entered the ALARM state, because "Threshold Crossed: 1 datapoint [10.5 (12/05/19 21:58:00)] was less than or equal to the threshold (15.0)." at "Sunday 12 May, 2019 22:03:17 UTC".
View this alarm in the AWS Management Console:
https://console.aws.amazon.com/cloudwatch/home?region=ap-southeast-2#s=Alarms&alarm=Fluid%20Level%20alert
Alarm Details:
- Name: Fluid Level alert
- Description: Fluid level has dropped below 15
- State Change: INSUFFICIENT_DATA -> ALARM
- Reason for State Change: Threshold Crossed: 1 datapoint [10.5 (12/05/19 21:58:00)] was less than or equal to the threshold (15.0).
- Timestamp: Sunday 12 May, 2019 22:03:17 UTC
Threshold:
- The alarm is in the ALARM state when the metric is LessThanOrEqualToThreshold 15.0 for 300 seconds.
Monitored Metric:
- MetricNamespace: Vat12
- MetricName: FluidLevel
- Dimensions:
- Period: 300 seconds
- Statistic: Average
- Unit: not specified
State Change Actions:
- OK:
- ALARM: [arn:aws:sns:ap-southeast-2::alertme]
- INSUFFICIENT_DATA:
答案 2 :(得分:0)
通过引入AWS IoT Events服务解决了该问题。
https://aws.amazon.com/iot-events/
我创建了一个检测器模型,该模型调用Lambda函数,该函数通过SNS主题发送电子邮件。
在引入此服务之前,必须进行自定义开发才能通过电子邮件实现按时间顺序发出警报。