在 CloudFront 中动态调整图像大小并立即将它们放在相同 URL 中:AWS CloudFront -> S3 -> Lambda -> CloudFront
Resize images on the fly in CloudFront and get them in the same URL instantly: AWS CloudFront -> S3 -> Lambda -> 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 中如何执行此操作的工作流程:
以下是 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 获取图像:
我想在 CloudFront 的 Behaviors
设置选项卡中创建新的缓存行为。
此行为不应缓存来自 Lambda 或 S3 的响应(不知道内部到底发生了什么),但仍应缓存任何后续请求到这个完全相同的调整大小的图像。
我正在尝试设置路径模式 -\d+x\d+\..+$
,在添加“Lambda 函数关联”中添加 Lambda 函数的 ARN
并设置事件类型 Origin Response
。
接下来,我将“默认 TTL”设置为 0
。
但是由于某些错误我无法保存该行为:
我们的方向是对的,还是这个“Lambda函数协会”的理念完全不同?
你走在正确的轨道上……也许……但至少有两个问题。
您在此处配置的 "Lambda Function Association" 称为 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.
第二个问题:
I am trying to set path pattern -\d+x\d+\..+$
你不能那样做。路径模式是支持 *
通配符的字符串匹配。它们不是正则表达式。不过,您可能会逃脱 /*-*x*.jpg
,因为 multiple wildcards appear to be supported.
终于解决了。虽然这不是真正的结构性解决方案,但它确实满足了我们的需要。
首先,感谢迈克尔的回答,我已经使用路径模式来匹配所有媒体类型。其次,缓存行为页面对我来说有点误导:Lambda 关联实际上是针对 Lambda@Edge 的,尽管我在缓存行为的所有工具提示中都没有看到这一点:您所看到的只是 Lambda。此功能无法帮助我们,因为我们不想仅仅因为那个特定问题而使用 Lambda@Edge 扩展我们的 AWS 服务范围。
解决方法如下:
我已经定义了多个缓存行为,我们支持的每种媒体类型都有一个:
对于每个缓存行为,我将 Default TTL
设置为 0
。
最重要的部分:在 Lambda 函数中,我在将调整后的图像放入 S3 时添加了 Cache-Control
header:
s3_resource.Bucket(BUCKET).put_object(Key=new_key,
Body=edited_image_obj,
CacheControl='max-age=12312312',
ContentType=content_type)
为了验证一切正常,我现在看到新的图像尺寸通过 CloudFront 中的缓存 header 提供:
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': ''
}
问题:
如果我们将 Lambda 函数重定向到 S3,它的效果非常好。 如果我们重定向到 CloudFront,它将进入重定向循环,因为 CloudFront 缓存 307(以及 301、302 和 303)。 一旦我们的 Lambda 函数重定向到 CloudFront,CloudFront 就会调用 API Getaway URL 而不是从 S3 获取图像:
我想在 CloudFront 的 Behaviors
设置选项卡中创建新的缓存行为。
此行为不应缓存来自 Lambda 或 S3 的响应(不知道内部到底发生了什么),但仍应缓存任何后续请求到这个完全相同的调整大小的图像。
我正在尝试设置路径模式 -\d+x\d+\..+$
,在添加“Lambda 函数关联”中添加 Lambda 函数的 ARN
并设置事件类型 Origin Response
。
接下来,我将“默认 TTL”设置为 0
。
但是由于某些错误我无法保存该行为:
我们的方向是对的,还是这个“Lambda函数协会”的理念完全不同?
你走在正确的轨道上……也许……但至少有两个问题。
您在此处配置的 "Lambda Function Association" 称为 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.
第二个问题:
I am trying to set path pattern
-\d+x\d+\..+$
你不能那样做。路径模式是支持 *
通配符的字符串匹配。它们不是正则表达式。不过,您可能会逃脱 /*-*x*.jpg
,因为 multiple wildcards appear to be supported.
终于解决了。虽然这不是真正的结构性解决方案,但它确实满足了我们的需要。
首先,感谢迈克尔的回答,我已经使用路径模式来匹配所有媒体类型。其次,缓存行为页面对我来说有点误导:Lambda 关联实际上是针对 Lambda@Edge 的,尽管我在缓存行为的所有工具提示中都没有看到这一点:您所看到的只是 Lambda。此功能无法帮助我们,因为我们不想仅仅因为那个特定问题而使用 Lambda@Edge 扩展我们的 AWS 服务范围。
解决方法如下:
我已经定义了多个缓存行为,我们支持的每种媒体类型都有一个:
对于每个缓存行为,我将 Default TTL
设置为 0
。
最重要的部分:在 Lambda 函数中,我在将调整后的图像放入 S3 时添加了 Cache-Control
header:
s3_resource.Bucket(BUCKET).put_object(Key=new_key,
Body=edited_image_obj,
CacheControl='max-age=12312312',
ContentType=content_type)
为了验证一切正常,我现在看到新的图像尺寸通过 CloudFront 中的缓存 header 提供: