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

时间:2017-02-17 22:13:52

标签: amazon-web-services caching amazon-s3 aws-lambda amazon-cloudfront

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中如何做到这一点:

enter image description here

以下是Python Lambda的结束方式:

return {
    'statusCode': '301',
    'headers': {'location': redirect_url},
    'body': ''
}

问题:

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

enter image description here

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

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

enter image description here

我们是在正确的方式,还是这个“Lambda函数协会”的想法完全不同?

2 个答案:

答案 0 :(得分:9)

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

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

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

enter image description here

对于每个缓存行为,我将Default TTL设置为0

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

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

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

enter image description here

答案 1 :(得分:1)

你走在正确的轨道上......也许......但至少有两个问题。

您在此处配置的“Lambda函数关联”称为Lambda @ Edge,但它尚不可用。可以访问它的唯一用户是已申请包含在有限预览中的用户。 "maximum allowed is 0"错误表示您不是预览参与者。我还没有看到任何关于何时会为所有帐户生效的公告。

但即使一旦它可用,它也不会像你期望的那样帮助你,因为我不相信Origin Response触发器允许你做任何事情来触发CloudFront尝试不同的目的地并按照重定向。如果您看到与此断言相矛盾的文档,请引起我的注意。

然而...... Lambda @ Edge对于在307上设置Cache-Control: no-cache非常有用,因此CloudFront不会对其进行缓存,但重定向本身仍需要一直返回浏览器。

另请注意,Lambda @ Edge仅支持Node,而不支持Python ......所以这可能不是您计划的一部分。我无法从这个问题中说出来。

Read about the Lambda@Edge limited preview

第二个问题:

  

我正在尝试设置路径模式-\d+x\d+\..+$

你做不到。路径模式是支持*通配符的字符串匹配。它们不是正则表达式。但是,从multiple wildcards appear to be supported开始,您可能会使用/*-*x*.jpg