S3/CloudFront,使用标题“Cache-Control: max-age=365000000, immutable”提供所有文件

Posted

技术标签:

【中文标题】S3/CloudFront,使用标题“Cache-Control: max-age=365000000, immutable”提供所有文件【英文标题】:S3/CloudFront, serve all files with header "Cache-Control: max-age=365000000, immutable" 【发布时间】:2017-03-21 23:14:06 【问题描述】:

我有一个 S3 存储桶,上面有 CloudFront CDN。

这个 S3 存储桶是“不可变的”,这意味着一旦我将文件上传到那里,我就永远不会删除或更新它。然后,所有客户端都非常积极地缓存来自 S3/CloudFront 的文件是安全的。

目前,Etag 运行良好,客户大部分时间都会收到 304 响应。但是获得 304 响应仍然涉及往返,这可以通过更积极的缓存来避免。

所以我想要这种行为:

CloudFront CDN 缓存永远不会失效,因为 S3 缓存永远不会改变。 CloudFront 不需要多次再次向 S3 请求文件。我想我已经使用 CloudFront 分配设置成功配置了。

CloudFront 应提供标头为 Cache-Control: max-age=365000000, immutable 的所有文件(immutable 是自 2016 年起部分支持的新值)

我不明白如何才能达到预期的效果。我应该在 CloudFront 还是 S3 级别处理它?我已经阅读了一些有关为每个 S3 文件配置适当标头的内容。难道没有一个全局设置来为所有文件提供我可以使用的自定义 http 标头吗?

【问题讨论】:

【参考方案1】:

我应该在 CloudFront 还是 S3 级别处理它?

目前在 Cloudfront 或 S3 中没有用于添加自定义 http 标头的全局设置。要将 http 标头添加到对象,它们必须在 S3 中单独设置在存储桶中的每个对象上。它们存储在对象的元数据中 - 并且可以在 AWS S3 控制台中每个对象的元数据部分中找到。

通常,在将对象添加到存储桶时设置标头是最简单的 - 这样做的确切机制取决于您使用的客户端应用程序或 sdk。

例如使用 aws cli 命令,您可以使用 --cache-control option:

aws s3 cp test.txt s3://mybucket/test2.txt \
    --cache-control max-age=365000000,immutable

要修改现有对象,s3cmd 实用程序有一个 modify 选项,如此 SO 答案中所述:https://***.com/a/22522942/6720449

或者您可以使用 aws s3 命​​令将对象复制回自身以修改元数据,如此 SO 答案中所述:https://***.com/a/29280730/6720449。例如替换存储桶中所有对象的元数据:

aws s3 cp s3://mybucket/ s3://mybucket/ --recursive --metadata-directive REPLACE \
    --cache-control max-age=365000000,immutable

CloudFront CDN 缓存永远不应失效

这是一个非常严格的要求 - 您无法阻止云端缓存永远失效。也就是说,如果创建 Cloudfront 的用户具有足够的权限,则没有任何设置可以防止创建 Cloudfront 失效。因此,以一种迂回的方式,您可以通过确保没有用户、角色或组有权使用cloudfront:CreateInvalidation IAM 权限在分发中创建失效来防止失效 - 这可能不切实际。

但是,Cloudfront 可能会出于一些原因选择违反后端的 Cache-Control 使缓存无效 - 例如如果设置了Maximum TTL 并且小于max-age。

【讨论】:

谢谢。我将使用修改命令。如果 CloudFront 有时会失效,那就不好了,但也没什么大不了的 您说的很对,“CloudFront CDN 缓存永远不应该失效” 非常严格。事实上,这根本不是一个合理的期望。没有一个单一的缓存——每个边缘都有一个,每个处理对象请求的边缘最初从源获取它。由于缺乏频繁访问(“流行”),对象也可以从任何给定的边缘驱逐。它是一个缓存......根据定义是易失的,但总体上非常一致。另见Why is Cloudfront evicting objects from cache within mere hours? 如果我理解正确,“不可变”与清除资产或创建此处所述的失效无关。这只是意味着无论我在 Cache-Control 标头上说什么,资产都不会过时。因此,对于 CloudFront,这仅意味着向源发送 REVALIDATION 请求没有任何意义,根据定义,它可以继续从该边缘位置提供陈旧的内容,并避免所有这些重新验证请求到达源。

以上是关于S3/CloudFront,使用标题“Cache-Control: max-age=365000000, immutable”提供所有文件的主要内容,如果未能解决你的问题,请参考以下文章

Cloudfront 域名无法使用 S3、Cloudfront 和 Route 53 将 HTTP 重定向到 HTTPS

CloudFront / S3 ETag:CloudFront 是不是可以在 CF TTL 过期之前发送更新的 S3 对象?

AWS S3+Cloudfront 访问被拒绝初学者问题

S3 / Cloudfront 下载限制

使用 S3/CloudFront 将 www 重定向到非 www,无需单独的存储桶

Amazon S3 Cloudfront 部署最佳实践