来自 Cloudfront 的 HIT 后来自 Cloudfront 的 MISS

Posted

技术标签:

【中文标题】来自 Cloudfront 的 HIT 后来自 Cloudfront 的 MISS【英文标题】:MISS from Cloudfront after HIT from Cloudfront 【发布时间】:2016-02-26 12:38:21 【问题描述】:

我正在切换到 Amazon Cloudfront 以在我的网站上提供图像。为了在我们最终上线时减少负载,我想通过点击图像 URL 来预热缓存(我从印度发出这些请求,并希望大多数用户从同一区域请求,因此不需要在全球所有边缘站点)。

问题是脚本使用 curl 来请求图像,当我在浏览器中访问相同的 URL 时,我从 Cloudfront 获得 MISS。所以 Cloudfront 正在为这两个请求制作两个对象副本。

我当前的 Cloudfront 配置将 Content-Type 请求标头转发到源。

我应该如何配置 Cloudfront 以便它根本不关心请求标头,并且一旦我发出请求(无论是 curl 还是使用浏览器),它应该为来自边缘而不是源的相同资源的所有未来请求提供服务。

请求/响应标头- 恐怕无法从外部访问 Cloudfront url(直到我们上线),但我正在发布请求/响应标头,这应该给你一个公平的想法。您还可以查看原始缓存标头 - https://origin.ixigo.com/image/upload/t_thumb,f_auto/r7y6ykuajvlumkp4lk2a.jpg

使用浏览器连续两次请求后的响应 远程地址:54.230.156.66:443 请求网址:https://youcannotaccess.com/image/upload/t_thumb,f_auto/r7y6ykuajvlumkp4lk2a.jpg 请求方法:GET 状态码:200 OK 响应标头 查看源代码 接受范围:字节 年龄:23​​ 缓存控制:公共,最大年龄=31557600 连接:保持活动 内容长度:8708 内容类型:图片/jpg 日期:格林威治标准时间 2015 年 11 月 27 日星期五 09:16:03 ETag:“-170562206” 最后修改时间:2014 年 6 月 29 日星期日 03:44:59 GMT 变化:接受编码 通过:1.1 7968275877e438c758292828c0593684.cloudfront.net (CloudFront) X-Amz-Cf-Id:fcbGLv8uBOP89qfR52OWa-NlqWkEREJPpZpy9ix0jdq8-a4oTx7lNw== X-后端:image6_40 X-Cache:来自云端 X-Cache-Hits:0 X-设备:电脑 X-DeviceType:pc X-Powered-By:xyz

现在使用 curl 请求了相同的 url,但我错过了 curl manu-mdc:cache manuc$ curl -I https://youcannotaccess.com/image/upload/t_thumb,f_auto/r7y6ykuajvlumkp4lk2a.jpg HTTP/1.1 200 正常 内容类型:图片/jpg 内容长度:8708 连接:保持活动 年龄:0 缓存控制:公共,最大年龄=31557600 日期:格林威治标准时间 2015 年 11 月 27 日星期五 09:16:47 ETag:“-170562206” 最后修改时间:2014 年 6 月 29 日星期日 03:44:59 GMT X-后端:image6_40 X-Cache-Hits: 0 X-设备:电脑 X-设备类型:pc X-Powered-By: xyz 变化:接受编码 X-Cache:来自云端的小姐 通过:1.1 4d42171c56a4c8b5c627040e6aa0938d.cloudfront.net (CloudFront) X-Amz-Cf-Id: fY0LXhp7NlqB-I8F5-1TIMnA6bONjPD3CEp7dsyVdykP-7N2mbffvw==

现在这将给 HIT manu-mdc:cache manuc$ curl -I https://youcannotaccess.com/image/upload/t_thumb,f_auto/r7y6ykuajvlumkp4lk2a.jpg HTTP/1.1 200 正常 内容类型:图片/jpg 内容长度:8708 连接:保持活动 缓存控制:公共,最大年龄=31557600 日期:格林威治标准时间 2015 年 11 月 27 日星期五 09:16:47 ETag:“-170562206” 最后修改时间:2014 年 6 月 29 日星期日 03:44:59 GMT X-后端:image6_40 X-Cache-Hits: 0 X-设备:电脑 X-设备类型:pc X-Powered-By: xyz 年龄:3 变化:接受编码 X-Cache:来自云端 通过:1.1 6877899d48ba844a34ea4378ce336f06.cloudfront.net (CloudFront) X-Amz-Cf-Id:qpPhbLX_5t2Xj0XZuZdjWD2w-BI80DUVyL496meQkLfSEn3ikt7hNg==

【问题讨论】:

您转发的任何请求标头都将用于缓存目的。必须如此,因为来源可能会因您发送的任何标头而改变响应。不需要转发 Content-Type 标头,因为标头转发不适用于“写入”请求(例如,PUTPOST)...所有标头都针对这些请求进行转发。白名单转发标头仅适用于GETHEAD(以及可能 OPTIONS)请求。 我不希望 CloudFront 使用标头进行缓存,这就是为什么我选择一个没有人会在 GET 请求中传递的标头(最初我没有转发任何标头,所以为了避免 CloudFront 默认行为我转发这个)。但它不应该有任何影响,因为我无论如何都没有通过它。问题是 - 我应该如何配置 CloudFront,以便它根本不关心请求标头,一旦我发出请求(无论是 curl 还是使用浏览器),它应该为来自边缘而不是源的同一资源的所有未来请求提供服务.我尝试了 None 所以应该还有别的东西。 那个,或者你误诊了这个问题。您在请求的每个对象中都看到了这种可重复的行为吗? 我已经用请求/响应更新了这个问题。是的,这是每个请求的可重复行为。 【参考方案1】:

这和这个问题类似:Why are two requests with different clients from the same computer cache misses on cloudfront?

根据您是否提供“Accept-Encoding: gzip”标头,CloudFront 边缘服务器会单独缓存对象。由于浏览器默认提供此标头,并且您的网站可能主要通过浏览器访问,我建议更改您的 curl 调用以包含此标头。

我遇到了同样的问题,在我的 curl 调用中进行了更改后,我第一次尝试通过浏览器(在进行 curl 调用之后)开始从浏览器中获得一个 Hit。

我注意到的另一件事是,CloudFront 要求在缓存之前下载完整的请求对象。如果您尝试通过在 curl 中指定字节范围来部分下载文件,则不会缓存预期的对象,只有下载的部分会被缓存为不同的对象。中间终止的卷曲也是如此。我尝试的其他选项是带有蜘蛛选项的 wget 调用,但它在内部仅执行 HEAD 调用,因此不会将内容缓存在边缘服务器上。

【讨论】:

感谢 Ashish,在 php 中使用 Curl,我不得不添加 [curl_setopt($ch, CURLOPT_ENCODING, "gzip");] 以最终在来自 php curl 和来自 Chrome 的调用之间获得相同的缓存行为浏览器。你是救生员!

以上是关于来自 Cloudfront 的 HIT 后来自 Cloudfront 的 MISS的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 Cloudfront 将来自源的所有请求强制为 HTTPS?

无法在 Safari 中加载跨域图像(来自 CloudFront)

来自 S3 Origin 的 Cloudfront 响应不断更改 CORS 标头

在 cloudformation 创建 cloudfront 后创建失效的最佳方法是啥?

r 倾向得分匹配来自http://stackoverflow.com/questions/23970707/propensity-score-matching-in-matchit-package的助

将 cloudfront 通配符 CNAME 子域路由到 s3 存储桶中的文件夹