背景
我在 S3 上托管一个静态网站,并使用 CloudFront 进行管理。我遇到的问题与 HTML 文件有关。
Amazon CloudFront 使用这些缓存控制标头来确定需要多久检查一次源文件是否有更新版本
我目前所做的
考虑到这一点,我已将 S3 Bucket 中的 HTML 文件设置为添加以下标题:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: Fri, 01 Jan 1990 00:00:00 GMT
在我第一次调用时samplefile.htm
,我看到了以下响应标头(Content-Type
为了切中要点,我排除了明显的标头(例如):
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Date:Sat, 10 Dec 2011 14:16:51 GMT
ETag:"a5890ace30a3e84d9118196c161aeec2"
Expires:Fri, 01 Jan 1990 00:00:00 GMT
Last-Modified:Sat, 10 Dec 2011 14:16:43 GMT
Server:AmazonS3
X-Cache:Miss from cloudfront
如您所见,我的Cache-Control
标头就在那里。问题是,如果我更新此文件并刷新,我会获得缓存的内容(而不是最新文件),并且我可以通过查看响应标头看到 CloudFront 正在提供其缓存版本:
X-Cache:Hit from cloudfront
摘要/问题
考虑到上述情况,如何在使用 CloudFront 时实现自动检索最新 HTML?
根据其常见问题解答,我应该能够使用 Cache-Control 标头来执行此操作,但我似乎无法使其工作。
遵循以下答案
最后我决定将我的 www CNAME 更改为直接指向我的 S3 存储桶。然后添加了一个名为“static”的新 CNAME,它指向 CloudFront。
这意味着 HTML 直接来自 S3,然后其所有 CSS/JS/IMG 引用都指向 static.mydomain.com
答案1
首先,Cloudfront 的目的是提供缓存内容 - 如果您尝试从 Cloudfront 提供未缓存的内容,在几乎所有情况下,它都比直接从 S3 提供慢(流媒体内容除外)。考虑一下从 Cloudfront 提供内容需要做什么 - 需要从原始服务器检索到地理位置靠近用户的位置 - 这意味着对于 Cloudfront 必须从原始服务器检索内容的请求,您会在请求中添加额外的延迟,并且用户接收内容的速度会更慢。只有当内容在边缘位置可用时,后续请求才会更快。
解决此问题的最佳方法是在更新页面时更改文件名 - 这将强制 Cloudfront 检索新内容。再次提醒,请记住 Cloudfront 通常用于媒体文件(包括图像)和样式/javascript - 而不是 html。本质上,您会将 HTML 放在 S3 上,将图像放在 Cloudfront 上 - 进行任何更改后,您都可以更改 Cloudfront 上文件的名称(例如 file-v1.jpg、file-v2.jpg 等)。另一种常用方法是包含带有版本信息的查询字符串。
另外,请记住,Cloudfront 不提供 gzip 压缩内容 - 这可能会导致响应速度比常规服务器慢(尽管在您的情况下,S3 也无法识别支持 gzip 的浏览器)。
最后,如果您愿意,可以使用失效强制 Cloudfront 丢弃其现有副本并从原始服务器获取新副本。但请注意,Cloudfront 每月只为您提供 1000 次免费失效,之后每次失效的费用为 0.005 美元。
Cloudfront 保留内容的最短时间为1小时,尽管默认值为 24 小时。因此,我会尝试将 max-age 设置为至少 3600。还请考虑使用 s-maxage 标头(用于共享 - 即代理内容)。亚马逊建议这缓存教程。
有一个最近的问题几天前已经纠正了这个问题
答案2
我认为到目前为止的答案虽然当时是正确的,但现在已经过时了,因为 Cloudfront 现在支持最小 TTL 0,并且 OP 最初尝试使用 cache-age=0 现在应该可以工作了。
您可能想要研究是否使用其他缓存控制标头,看它们是否会产生您想要的结果 - 您可能只需要 max-age。您可能希望 Cloudfront 检查 S3 以查看 HTML 文件是否已更改。如果已更改,Cloudfront 可以获取并返回新文件。如果没有,它可以从其现有缓存中为客户端提供服务(节省 S3 带宽,并以更快、更本地的方式为客户端提供服务)。
Cloudfront 的目的在于提供缓存内容,是的,但是现在这包括有时会发生变化的内容,但如果没有发生变化则可以缓存。
Ps 查询字符串现在也可以与 Cloudfront 一起使用(如果您为相关来源配置“行为” - 另一个新功能),但是某些代理可能仍然无法缓存带有查询字符串的任何文件。
亚马逊开发人员指南:到期1
答案3
不确定 CloudFront 如何处理您拥有的标头,但如果您未指定任何标头,则刷新对象的默认时间为 24 小时。
刷新对象的方法之一是使内容无效。查看以下链接了解更多信息。 http://blog.cloudberrylab.com/2010/08/how-to-manage-cloudfront-object.html