我在 CloudFront 分配上设置了自定义对象缓存。为什么我的分配使用我的源的缓存设置?

上次更新时间:2019 年 7 月 17 日

我的 Amazon CloudFront 分配具有缓存行为,对象缓存设置为自定义,但我的分配仍然使用我的源的缓存设置。如何解决此问题? 

简短描述

当您自定义对象缓存时,可以配置默认 TTL最小 TTL最大 TTL。CloudFront 根据源是否返回缓存标头来使用这些参数:

  • 如果源不返回缓存标头,则分配使用默认 TTL。
  • 如果源返回的缓存标头小于最小 TTL,则分配使用最小 TTL。
  • 如果源返回的缓存标头大于最大 TTL,则分配使用最大 TTL。

注意:即使 CloudFront 根据最小 TTL 或最大 TTL 缓存响应,对客户端的响应也包含源的缓存标头。源的缓存标头可以由任何私有缓存使用,例如浏览器或代理。

如果您的 CloudFront 分配未根据您设置的缓存行为自定义值进行缓存,请检查源。验证源是否有存在冲突的缓存标头。

解决方法

要验证源缓存标头是否与您的分配的自定义对象缓存冲突,请根据您遇到的问题按照以下说明操作:

最小 TTL 且默认 TTL 设置为 0,但仍然有来自 CloudFront 的命中

如果存在来自 CloudFront 的命中,即使请求 URI 与具有最小 TTL 且默认 TTL 设置为 0 的缓存行为路径匹配,也请检查来自 CloudFront 的响应。验证响应是否将 X-Cache 标头显示为“Hit from cloudfront”或“RefreshHit from cloudfront”:

< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 437
< Connection: keep-alive
< Date: Sat, 03 Feb 2018 19:26:45 GMT
< Last-Modified: Sat, 03 Feb 2018 19:25:24 GMT
< ETag: "example12345abcdefghijklmno54321"
< Cache-Control: max-age=300, Public
< Accept-Ranges: bytes
< Server: AmazonS3
< Age: 14
< X-Cache: Hit from cloudfront

如果 X-Cache 标头是“Hit from cloudfront”或“RefreshHit from cloudfront”,则该请求是通过边缘站点的缓存提供的。

查看 Cache-Control、Expires 和 Age 标头的其余响应。Cache-Control 和 Expires 标头是行为缓存标头,用于告知中介 (CloudFront) 或私有(浏览器)缓存如何存储请求。Age 标头显示缓存响应花费的时间。

如果 Cache-Control 的 max-age 值大于 Age 的值,则缓存的响应将被视为新响应,并从边缘站点提供。如果 Expires 日期仍在将来,则缓存的响应也被视为新响应。即使缓存行为路径具有最小 TTL,且默认 TTL 设置为 0,也会发生这种情况。

最大 TTL 和默认 TTL 大于 0,但存在来自 CloudFront 的未命中

如果存在来自 CloudFront 的未命中,即使请求 URI 与具有最大 TTL 和默认 TTL 设置为大于 0 的值的缓存行为路径匹配,也请检查来自 CloudFront 的响应。验证响应是否将 X-Cache 标头显示为“Miss from cloudfront”:

< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 437
< Connection: keep-alive
< Date: Sat, 03 Feb 2018 19:26:45 GMT
< Last-Modified: Sat, 03 Feb 2018 19:25:24 GMT
< ETag: "example12345abcdefghijklmno54321"
< Cache-Control: no-cache, no-store
< Accept-Ranges: bytes
< Server: AmazonS3
< X-Cache: Miss from cloudfront

如果 X-Cache 标头是“Miss from cloudfront”,则请求是从源检索的,而不是由缓存提供。

查看响应中的 Cache-Control 标头。如果 Cache-Control 的值为“no-store”,则标头指示 CloudFront 不缓存响应。如果 Cache-Control 的值为“no-cache”,则标头指示 CloudFront 在返回缓存响应之前验证源。这些指令会取代最大 TTL 和默认 TTL CloudFront 设置。

注意:不是来自缓存的响应不会有 Age 标头。

CloudFront 缓存错误响应

默认情况下,CloudFront 会将错误响应从源转发到客户端。此外,CloudFront 会将源的错误响应缓存 5 分钟(300 秒)。

如果来自源的错误响应包含 Cache-Control 标头,则 CloudFront 会使用相关 TTL(而不是默认的 5 分钟)来缓存错误。除非在自定义错误响应中另行指定,否则 CloudFront 不会缓存自己的错误响应。

要确定错误响应是来自源还是 CloudFront,请检查服务器标头。要确定错误是否为缓存响应,请检查 Age 标头 – 缓存响应包括 Age 标头。

以下示例是来自 Amazon Simple Storage Service (Amazon S3) 源的错误,该错误是缓存响应:

< HTTP/1.1 403 Forbidden
< Content-Type: application/xml
< Transfer-Encoding: chunked
< Connection: keep-alive
< Date: Sat, 03 Feb 2018 21:07:51 GMT
< Server: AmazonS3
< Age: 12
< X-Cache: Error from cloudfront

以下示例是来自 CloudFront 的错误,该错误不是缓存响应: 

< HTTP/1.1 403 Forbidden
< Server: CloudFront
< Date: Sat, 03 Feb 2018 21:14:53 GMT
< Content-Type: text/xml
< Content-Length: 146
< Connection: keep-alive
< X-Cache: Error from cloudfront

确定冲突的缓存标头后,更新源

确定哪些缓存标头会取代分配的自定义对象缓存后,请按照下列步骤操作:

  1. 确定应用标头的 Web 服务器配置的位置。
  2. 删除应用标头的行。
  3. 重启服务器。
  4. 直接测试您的源,以确保响应中不再返回缓存标头。
  5. 在整个 CloudFront 分配上运行失效以应用更改。

这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?