【问题标题】:Cloudfront createInvalidation randomly not being fired from LambdaCloudfront createInvalidation 不会被 Lambda 随机触发
【发布时间】:2020-12-30 18:46:48
【问题描述】:

我遇到了从 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 代码来看,我可能遗漏了什么吗?

谢谢。

【问题讨论】:

    标签: amazon-s3 aws-lambda amazon-cloudfront aws-sdk-js


    【解决方案1】:

    这是因为 Lambda 运行时模型。当您使用异步函数作为处理程序时,Lambda 执行在返回时被视为“完成”(返回的 Promise 已结算)。在您的代码中,您创建了一个失效,但处理函数返回在失效完成之前

    当函数被认为“完成”时,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
    };
    

    【讨论】:

    • 你是对的,它现在绝对可以正常工作。我知道我的处理程序在调用createInvalidation 方法后立即返回的事实,但我天真地相信,一旦被调用,处理程序返回后,方法将在后台继续执行。我可以得到我的带有console.log 调用的回调没有被调用,但我真的没想到失效方法在完成之前会立即中止。非常感谢您的回答,这篇文章做得很好,也许我应该阅读更多关于 Lambda 执行模型的内容。
    猜你喜欢
    • 2020-12-08
    • 2021-11-27
    • 2020-02-09
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    相关资源
    最近更新 更多