【发布时间】:2018-06-09 17:25:23
【问题描述】:
我正在创建一个 cloudwatch 事件,该事件应该在未来的特定时间调用 aws lambda 函数。我正在使用 aws nodejs sdk,如下所述:http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html
创建 cloudwatch 事件的代码块如下所示:
module.exports.createReservationReminder = function (reservationModel, user, restaurant) {
return new Promise(function (resolve, reject) {
const ruleName = "rsv_" + reservationModel.reservationId;
const description = "Reservation reminder of `" + user.name + "` @ `" + restaurant.title + "` on `" + reservationModel.time + "`";
let reservationTime = reservationModel.time;
let lambdaFunctionName = module.exports.buildLamdaFunctionArn("restaurant")
let alertTime = moment(reservationTime).tz(AppConfig.defaultTimezone).subtract( // Create alert 45 minute before a reservation
45,
'minutes'
);
let lambda = new AWS.Lambda({
accessKeyId: AppConfig.accessKeyId,
secretAccessKey: AppConfig.secretAccessKey,
region: AppConfig.region
});
let scheduleExpression1 = "cron(" + alertTime.utc().format('m H D MMM ? YYYY') + ')';
let ruleParams = {
Name: ruleName,
Description: description,
ScheduleExpression: scheduleExpression1,
State: 'ENABLED',
};
cloudwatchevents.deleteRule({Name: ruleName}, function (err, deleteRuleData) { //remove if a previous rule was created halfway
cloudwatchevents.putRule(ruleParams, function (err, ruleData) { //create the rule
if (err) {
reject(err)
}
else {
let lambdaPermission = {
FunctionName: lambdaFunctionName,
StatementId: ruleName,
Action: 'lambda:InvokeFunction',
Principal: 'events.amazonaws.com',
SourceArn: ruleData.RuleArn
};
let removePermission = {
FunctionName: lambdaFunctionName,
StatementId: ruleName,
}
//now to create the rule's target, need to add permission to lambda
lambda.removePermission(removePermission, function (err, removeLambdaData) { //remove if rule of same name was added as permission to this lambda before, ignore if rule not found error is thrown
lambda.addPermission(lambdaPermission, function (err, lamdaData) { //now add the permission
if (err) {
reject(err) // FAIL : throws error PolicyLengthExceededException after ~50 cloudwatch events are registered to this lambda function
}
else {
let targetParams = {
Rule: ruleName,
Targets: [
{
Arn: module.exports.buildLamdaFunctionArn("restaurant"),
Id: ruleName,
Input: JSON.stringify({
func: "notifyUserOfUpcomingReservation",
data: {
reservationId: reservationModel.reservationId
}
}),
},
]
};
cloudwatchevents.putTargets(targetParams, function (err, targetData) {
if (err) {
reject(err)
}
else {
resolve(targetData)
}
})
}
})
})
}
});
})
})
}
上述功能在前约 50 次运行良好(因此我可以轻松地提醒 50 次预订。)但是,它最终总是会失败:
PolicyLengthExceededException Lambda 函数访问策略限制为 20 KB。
HTTP 状态码:400
这是有道理的,因为政策文件不能太大。 那么解决这个问题的正确方法是什么:使用 lambda 函数目标进行无限的 cloudwatch 事件提醒。
【问题讨论】:
-
您正在为每个需要触发的事件创建一个事件?由于其他原因,我认为这不会扩大规模。似乎更好的策略是每 5 分钟触发一次并查询表(例如 DynamoDB 或 RDS)以查看哪些未发送的通知需要“现在”发送,然后通过调用第二个来处理它们。 Lambda 函数。想法?
-
由于对我可以拥有的 cloudwatch 事件数量的限制,最终做到了:(
标签: amazon-web-services aws-lambda aws-sdk amazon-iam amazon-cloudwatch