如果我使用带有S3源的cloudfront来为具有两个文件的网站提供服务。让我们说index.html和app.js.现在,如果我对html文件和app.js进行更改,例如删除一些函数并添加一些新函数。现在,云端的工作方式是文件的截止日期我认为是24小时。因此,一旦24小时结束,那么对cloudfront的请求将检查s3存储桶以查看文件是否已更改。如果文件同时到期,这很好,但如果html文件在javascript文件后4小时到期怎么办?
这意味着旧的HTML文件可能正在调用旧的javascript文件中存在的函数。但是,正在提供新的Javascript文件,它不再具有此功能。这会导致错误。
要处理此问题,您可以为这两个文件发送无效请求,并在完成后将提供新内容。失效请求可能需要一些时间,我个人已经看到10-15分钟的请求完成。因此,如果我将已编辑的文件(html,js)推送到我的S3源并发送无效请求,则需要15分钟才能完成。然后就在我发送失效请求之后,js文件到期并且使用旧的HTML文件拉出新的JS文件...我的网站可能会抛出大约15分钟的错误?
如果我从服务器提供html并从cloudfront / S3中提取js,该怎么办?我是否必须使用cloudfront上成功的失效请求来定时更改本地服务器上的html?
答案 0 :(得分:2)
失效需要时间并且不是原子的。纽约的某个人可能会看到新文件,而悉尼的某个人正在使用旧的/缓存文件。
有几个选择:
将每个对象的缓存时间设置为合理的短时间,例如10秒。在许多方面,这消除了缓存的优势。
Cache-Control
标题为您带来优势。Here's the spec和here's a good walkthrough。有几件事你可以利用。以下是一些例子:
cache-control: no-cache
cache-control: must-revalidate, s-maxage=10, max-age=600
最终,在版本重要时执行此操作的最佳方法是使用唯一的文件名。例如,您可以加载styles-1.css
,然后下一版本的html(或生成html的代码)将请求styles-2.css
。这就是Rails Asset Pipeline对config.assets.digest
所做的事情。许多其他框架都有相同的东西 - Grails有Asset Pipeline。 Django有Django Compressor或Django Pipeline。节点可以执行此操作via Grunt(可能有另一种方式)。 ASP / .NET有Cassette或Combres(都称之为"版本控制")。
这最后一个选项是最好的。这意味着您的缓存文件可以有很长的使用寿命。我的一个项目默认为一年的缓存时间。