在CloudFront中动态调整图像大小并立即将它们放在同一个URL中:AWS CloudFront - > S3 - > Lambda - > CloudFront

kat*_*ata 19 caching amazon-s3 amazon-web-services amazon-cloudfront aws-lambda

TLDR:我们必须通过为来自Lambda函数的响应创建新的缓存行为来欺骗CloudFront 307重定向缓存.

你不会相信我们有多接近实现这一目标.我们在最后一步中陷入了沉重的困境.

商业案例:

我们的应用程序将图像存储在S3中,并使用CloudFront为其提供服务,以避免全球任何地理上的减速.现在,我们希望对设计非常灵活,并能够直接在CouldFront URL中请求新的图像尺寸!每个新的图像大小将按需创建,然后存储在S3中,因此第二次请求时,它将非常快速地提供,因为它将存在于S3中,并且还将缓存在CloudFront中.

让我们说用户上传了图像chucknorris.jpg.只有原始图像将存储在S3中,并且将在我们的页面上提供,如下所示:

//xxxxx.cloudfront.net/chucknorris.jpg

我们计算出我们现在需要显示200x200像素的缩略图.因此我们将图像src放在我们的模板中:

//xxxxx.cloudfront.net/chucknorris-200x200.jpg

当请求这个新的大小时,亚马逊网络服务必须在同一个存储桶中使用所请求的密钥即时提供.这样,图像将直接加载到CloudFront的同一URL中.

我在架构概述和工作流程中制作了一幅丑陋的图纸,介绍了我们如何在AWS中执行此操作:

在此输入图像描述

以下是Python Lambda的结束方式:

return {
    'statusCode': '301',
    'headers': {'location': redirect_url},
    'body': ''
}
Run Code Online (Sandbox Code Playgroud)

问题:

如果我们将Lambda函数重定向到S3,它就像魅力一样.如果我们重定向到CloudFront,它将进入重定向循环,因为CloudFront缓存307(以及301,302和303).只要我们的Lambda函数重定向到CloudFront,CloudFront就会调用API Getaway URL而不是从S3获取图像:

在此输入图像描述

我想在CloudFront的Behaviors设置选项卡中创建新的缓存行为.此行为不应缓存来自Lambda或S3的响应(不知道内部究竟发生了什么),但仍应将任何后续请求缓存到此相同的已调整大小的图像.我正在尝试设置路径模式-\d+x\d+\..+$,添加Lambda函数的ARN添加"Lambda函数关联"并设置事件类型Origin Response.接下来,我将"默认TTL"设置为0.

但由于一些错误,我无法保存行为:

在此输入图像描述

我们是在正确的方式,还是这个"Lambda功能协会"的想法完全不同?

kat*_*ata 9

最后我能够解决它.虽然这不是一个真正的结构解决方案,但它可以满足我们的需求.

首先,感谢Michael的回答,我使用了路径模式来匹配所有媒体类型.其次,Cache Behavior页面对我来说有点误导:事实上Lambda关联是针对Lambda @ Edge的,虽然我没有在缓存行为的所有工具提示中看到这一点:你看到的只是Lambda.此功能无法帮助我们,因为我们不希望仅因为该特定问题而使用Lambda @ Edge扩展我们的AWS服务范围.

这是解决方案的方法:
我已经定义了多个缓存行为,我们支持每种媒体类型一个:

在此输入图像描述

对于每个缓存行为我设置的Default TTL0.

最重要的部分:在Lambda函数中,我Cache-Control在将调整后的图像放入S3时为其添加了一个标题:

s3_resource.Bucket(BUCKET).put_object(Key=new_key, 
                                      Body=edited_image_obj,
                                      CacheControl='max-age=12312312',
                                      ContentType=content_type)
Run Code Online (Sandbox Code Playgroud)

为了验证一切正常,我现在看到新的图像维度与CloudFront中的缓存头一起提供:

在此输入图像描述

  • 回答我自己的愚蠢问题.我读了另一篇关于这篇https://sketchboard.io/blog/serverless-image-resize-with-amazon-lambda的博文,解释了为什么需要`max-age`.CloudFront将使用它来确定缓存对象的时间(在第一次运行之后,使用默认值0).优秀的问答在这里!@katericata. (2认同)