Cloudfront createInvalidation 随机不会从 Lambda 触发
Cloudfront createInvalidation randomly not being fired from Lambda
我在从 AWS Lambda 创建 Cloudfront 失效时遇到了问题。
我的情况非常简单:我设置了一个 Lambda 处理程序,由特定 S3 对象的创建和删除触发,以便在我的 Cloudfront 分发版上执行缓存版本的失效。这是功能代码,使用nodejs编写:
const AWS = require('aws-sdk');
exports.handler = async function (event, context) {
const cloudFront = new AWS.CloudFront();
const invalidationParams = {
DistributionId: "XXXX",
InvalidationBatch: {
CallerReference: Date.now().toString(),
Paths: {
Quantity: 2,
Items: [
"/index.html",
"/service-worker.js"
]
}
}
};
cloudFront.createInvalidation(invalidationParams, (error, data) => {
if (error) {
console.log(error, error.stack);
} else {
console.log("Invalidation results", data);
}
});
};
如您所见,没有什么太复杂的。
现在,大多数时候处理程序执行时什么都不做,我正在查看日志,除了请求 ID 和开始和结束时间戳之外,没有任何内容被打印出来,甚至没有 Cloudfront 错误,这让我想知道发生了什么。
在连续执行四到五次手动测试后,正确创建了一个失效,但日志没有报告它。再触发一次,然后打印前一个 运行 的无效结果。我觉得这很奇怪和令人困惑。
从上下文和 Lambda 代码来看,我可能遗漏了什么吗?
谢谢。
这是因为 Lambda 运行时模型。当您使用异步函数作为处理程序时,Lambda 执行在 returns(返回的 Promise 已解决)时被视为“完成”。在您的代码中,您创建了一个失效,但是处理函数 returns 在失效完成之前 .
Lambda 在函数被认为“完成”时冻结函数,它不会等待 createInvalidation
完成。有时有效有时无效的原因是 Lambda 冻结函数和无效请求之间存在竞争条件。我写了一篇article with a more in-depth exlanation
解决方案很简单:在完成处理程序之前等待 createInvalidation 完成:
const AWS = require('aws-sdk');
exports.handler = async function (event, context) {
const cloudFront = new AWS.CloudFront();
const invalidationParams = {
DistributionId: "XXXX",
InvalidationBatch: {
CallerReference: Date.now().toString(),
Paths: {
Quantity: 2,
Items: [
"/index.html",
"/service-worker.js"
]
}
}
};
await cloudFront.createInvalidation(invalidationParams).promise();
// by the time the handler reaches this point the invalidation made it through
};
我在从 AWS Lambda 创建 Cloudfront 失效时遇到了问题。
我的情况非常简单:我设置了一个 Lambda 处理程序,由特定 S3 对象的创建和删除触发,以便在我的 Cloudfront 分发版上执行缓存版本的失效。这是功能代码,使用nodejs编写:
const AWS = require('aws-sdk');
exports.handler = async function (event, context) {
const cloudFront = new AWS.CloudFront();
const invalidationParams = {
DistributionId: "XXXX",
InvalidationBatch: {
CallerReference: Date.now().toString(),
Paths: {
Quantity: 2,
Items: [
"/index.html",
"/service-worker.js"
]
}
}
};
cloudFront.createInvalidation(invalidationParams, (error, data) => {
if (error) {
console.log(error, error.stack);
} else {
console.log("Invalidation results", data);
}
});
};
如您所见,没有什么太复杂的。 现在,大多数时候处理程序执行时什么都不做,我正在查看日志,除了请求 ID 和开始和结束时间戳之外,没有任何内容被打印出来,甚至没有 Cloudfront 错误,这让我想知道发生了什么。 在连续执行四到五次手动测试后,正确创建了一个失效,但日志没有报告它。再触发一次,然后打印前一个 运行 的无效结果。我觉得这很奇怪和令人困惑。
从上下文和 Lambda 代码来看,我可能遗漏了什么吗?
谢谢。
这是因为 Lambda 运行时模型。当您使用异步函数作为处理程序时,Lambda 执行在 returns(返回的 Promise 已解决)时被视为“完成”。在您的代码中,您创建了一个失效,但是处理函数 returns 在失效完成之前 .
Lambda 在函数被认为“完成”时冻结函数,它不会等待 createInvalidation
完成。有时有效有时无效的原因是 Lambda 冻结函数和无效请求之间存在竞争条件。我写了一篇article with a more in-depth exlanation
解决方案很简单:在完成处理程序之前等待 createInvalidation 完成:
const AWS = require('aws-sdk');
exports.handler = async function (event, context) {
const cloudFront = new AWS.CloudFront();
const invalidationParams = {
DistributionId: "XXXX",
InvalidationBatch: {
CallerReference: Date.now().toString(),
Paths: {
Quantity: 2,
Items: [
"/index.html",
"/service-worker.js"
]
}
}
};
await cloudFront.createInvalidation(invalidationParams).promise();
// by the time the handler reaches this point the invalidation made it through
};