在决定是否缓存对象以及缓存多长时间时,CloudFront 使用以下逻辑:
检查任何具有这些值的Cache-Control 响应标头:
no-cache
no-store
private
如果遇到任何这些情况,请停止并将对象的 TTL¹ 设置为 Minimum TTL 的配置值。非零值意味着 CloudFront 将缓存原本不会缓存的对象。
否则,请查找源的指令以了解对象可以缓存多长时间。 按顺序找到以下响应标头之一:
Cache-Control: s-maxage=x
Cache-Control: max-age=x
-
Expires
在使用此排序遇到的第一个值处停止,然后继续下一步。
如果未找到值,请使用默认 TTL。停下来。
否则,使用上一步发现的值:
- 如果小于Minimum TTL,则设置对象的TTL为Minimum TTL;否则,
- 如果大于最大TTL,则设置对象的TTL为最大TTL;否则,
- 使用在上一步中找到的值作为对象的 TTL。
见https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html。
请务必注意,TTL 决定了 CloudFront允许 缓存响应的时间。它确实不规定 CloudFront 需要多长时间来缓存响应。如果对象很少被访问,CloudFront 可以在 TTL 过期之前从缓存中逐出对象。
将一些(但不是全部)标头列入白名单以转发到源并不会改变上述任何逻辑。
它改变的是如何评估对象以确定缓存的响应是否可用。
例如,如果您将 Origin 标头转发到源,则 Origin 标头的每个唯一值都会创建不同的缓存条目。除了 Origin 标头之外,两个相同的请求被视为不同的对象......因此,如果稍后对同一资源的请求包含 Origin: https://two.example.com,则不会使用 Origin: https://one.example.com 的缓存响应。两者都将被发送到源,并且都将被独立缓存,以用于为具有相同匹配请求标头的未来请求提供服务。
CloudFront 这样做是因为如果您需要将标头转发到源,那么这意味着源可能会对列入白名单的标头的不同值做出不同的反应......因此它们会被单独缓存。
不必要地转发标头会因此不必要地降低缓存命中率。
对于 CloudFront 可以缓存的同一资源的不同副本的数量没有记录限制,具体取决于不同的标头。
但是将 all 标头转发到源将减少任何未来请求真正相同的机会几乎为零。这可能会消耗大量缓存存储,存储永远不会再被重用的对象,因此 CloudFront 将此视为一种特殊情况,并且在这种情况下不允许任何缓存。因此,您需要将最小 TTL 设置为 0 以保持一致性。
¹此处使用的对象的 TTL 是指 CloudFront 的每个缓存对象的内部计时器,该计时器跟踪允许继续为缓存对象提供多长时间而无需与源进行核对。 CloudFront 中对象的 TTL 只有 CloudFront 知道,因此该值不会影响浏览器缓存。