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
};