CloudFront - 错误时的意外缓存行为
CloudFront - Unexpected caching behaviour on error
当我的源抛出错误时,我从 CloudFront 看到了一个奇怪的行为。
我的场景如下:
初始请求:
- 命中 CF,缓存中没有任何内容
- CF 向来源发出请求,returns 回复如下:
- 状态码:200
- etag header: "example-etag"
- cache-control header: public, must-revalidate, max-age=0
- body:例子body
- 客户端收到的响应如下:
- 状态码:200
- etag header: "example-etag"
- cache-control header: public, must-revalidate, max-age=0
- body:例子body
然后我对源进行更改以确保它抛出如下错误响应:
- 状态码:500
- etag header: "a-different-etag"
- cache-control header: no-store
- body: 内部服务器错误
当发出另一个请求(发送 header if-none-match: "example-etag"
)时,我预计会发生以下情况:
- 命中 CF,它的缓存中有第一个请求的结果,但它已经过期并且必须通过源重新验证
- CF 向 returns 上述错误响应
的来源发出请求
- 此响应的 etag 与缓存响应的 etag 不同
- 错误响应被中继到客户端但未被 CF 存储
我在第二个请求中实际看到的内容:
- 命中 CF,它的缓存中有第一个请求的结果,但它已经过期并且必须通过源重新验证
- CF 向 returns 上述错误响应
的来源发出请求
- 客户收到以下信息:
- 状态码:200
- if-none-match header: "example-etag"
- cache-control header: public, must-revalidate, max-age=0
- x-cache header:来自云端的 RefreshHit
- body:例子body
这是预期的行为吗?如果是,我如何让 CF 将错误转发给客户端?
多亏了凯文的评论,我才能够理解这实际上是预期的行为。
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html 的文档解释说:
If the origin is unreachable and minimum TTL is greater than 0, CloudFront serves the object that it got from the origin previously. To avoid this behavior, include the Cache-Control: stale-if-error=0 directive with the object returned from the origin. This causes CloudFront to return an error in response to future requests if the origin is unreachable, rather than returning the object that it got from the origin previously.
我可以确认在 Cache-Control
header 中返回 stale-if-error=0
有效,并且错误已转达给用户。
当我的源抛出错误时,我从 CloudFront 看到了一个奇怪的行为。
我的场景如下:
初始请求:
- 命中 CF,缓存中没有任何内容
- CF 向来源发出请求,returns 回复如下:
- 状态码:200
- etag header: "example-etag"
- cache-control header: public, must-revalidate, max-age=0
- body:例子body
- 客户端收到的响应如下:
- 状态码:200
- etag header: "example-etag"
- cache-control header: public, must-revalidate, max-age=0
- body:例子body
然后我对源进行更改以确保它抛出如下错误响应:
- 状态码:500
- etag header: "a-different-etag"
- cache-control header: no-store
- body: 内部服务器错误
当发出另一个请求(发送 header if-none-match: "example-etag"
)时,我预计会发生以下情况:
- 命中 CF,它的缓存中有第一个请求的结果,但它已经过期并且必须通过源重新验证
- CF 向 returns 上述错误响应 的来源发出请求
- 此响应的 etag 与缓存响应的 etag 不同
- 错误响应被中继到客户端但未被 CF 存储
我在第二个请求中实际看到的内容:
- 命中 CF,它的缓存中有第一个请求的结果,但它已经过期并且必须通过源重新验证
- CF 向 returns 上述错误响应 的来源发出请求
- 客户收到以下信息:
- 状态码:200
- if-none-match header: "example-etag"
- cache-control header: public, must-revalidate, max-age=0
- x-cache header:来自云端的 RefreshHit
- body:例子body
这是预期的行为吗?如果是,我如何让 CF 将错误转发给客户端?
多亏了凯文的评论,我才能够理解这实际上是预期的行为。
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html 的文档解释说:
If the origin is unreachable and minimum TTL is greater than 0, CloudFront serves the object that it got from the origin previously. To avoid this behavior, include the Cache-Control: stale-if-error=0 directive with the object returned from the origin. This causes CloudFront to return an error in response to future requests if the origin is unreachable, rather than returning the object that it got from the origin previously.
我可以确认在 Cache-Control
header 中返回 stale-if-error=0
有效,并且错误已转达给用户。