我在处理 CORS 请求时遇到了延迟,但直接请求处理得很好。我使用它通过 HTTP 分发媒体流,因此减少启动延迟非常重要。
从通过 CloudFront 分发版(通过浏览器或 curl 的直接请求)获得媒体清单到我们网站上的播放器发出的 CORS 请求成功返回,大约需要 90-180 秒。我在 CloudFront 分发版中启用了 OPTIONS 请求转发,并且还包含了 OPTIONS 请求的结果。我在下面包含了 curl 请求的结果和来自 Chrome Dev 工具网络选项卡的相应结果。请注意,这些请求是在 15 秒内从同一客户端发出的(curl 请求先发送)。
=== CURL 请求 ===
* Trying 54.192.135.101...
* Connected to <exampleDistributionID>.cloudfront.net (1.1.1.1) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /opt/local/share/curl/curl-ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=Washington; L=Seattle; O=Amazon.com, Inc.; CN=*.cloudfront.net
* start date: Sep 17 00:00:00 2015 GMT
* expire date: Dec 15 23:59:59 2016 GMT
* subjectAltName: <exampleDistributionID>.cloudfront.net matched
* issuer: C=US; O=Symantec Corporation; OU=Symantec Trust Network; CN=Symantec Class 3 Secure Server CA - G4
* SSL certificate verify ok.
> GET /path/to/manifest/stream.m3u8 HTTP/1.1
> Host: <exampleDistributionID>.cloudfront.net
> User-Agent: curl/7.47.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/vnd.apple.mpegurl
< Content-Length: 1435
< Connection: keep-alive
< Server: nginx/1.9.10
< Date: Sun, 17 Apr 2016 00:26:06 GMT
< Last-Modified: Sun, 17 Apr 2016 00:26:05 GMT
< ETag: "5712d81d-59b"
< Cache-Control: no-cache
< Access-Control-Allow-Origin: *
< Accept-Ranges: bytes
< X-Cache: Miss from cloudfront
< Via: 1.1 f687c6e8ce478528ab87681ac35779ab.cloudfront.net (CloudFront)
< X-Amz-Cf-Id: P01_dDWZRWZ0lzAqROqOMnaipstK484vPWnicw3F0kcG_7elxBGNkQ==
<...Content of stream.m3u8...>
===Chrome 请求===
Chrome 开发者工具网络选项卡的屏幕截图,显示收到的 404 错误
===OPTIONS 请求===
* Trying 1.1.1.1...
* Connected to <exampleDistributionID>.cloudfront.net (1.1.1.1) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /opt/local/share/curl/curl-ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=Washington; L=Seattle; O=Amazon.com, Inc.; CN=*.cloudfront.net
* start date: Sep 17 00:00:00 2015 GMT
* expire date: Dec 15 23:59:59 2016 GMT
* subjectAltName: <exampleDistributionID>.cloudfront.net matched
* issuer: C=US; O=Symantec Corporation; OU=Symantec Trust Network; CN=Symantec Class 3 Secure Server CA - G4
* SSL certificate verify ok.
> OPTIONS /path/to/manifest/stream.m3u8 HTTP/1.1
> Host: <exampleDistributionID>.cloudfront.net
> User-Agent: curl/7.47.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Content-Length: 0
< Connection: keep-alive
< Server: nginx/1.9.10
< Date: Sun, 17 Apr 2016 22:05:15 GMT
< Access-Control-Allow-Origin: http://my.origin.com
< Access-Control-Allow-Methods: GET, OPTIONS
< Access-Control-Allow-Headers: Authorization
< Access-Control-Allow-Credentials: true
< X-Cache: Miss from cloudfront
< Via: 1.1 ed2825b48bb51b4febd93a82e71f7ed9.cloudfront.net (CloudFront)
< X-Amz-Cf-Id: WY-KPfTlNTenTjWyYF9GS4ikyrGMQONAm4mXpbuKpHzfBk_xKfxG2w==
<
* Connection #0 to host <exampleDistributionID>.cloudfront.net left intact
我不知道我的配置中存在什么错误,如果能提供任何帮助我将非常感激。
答案1
CloudFront 尝试通过缓存错误响应来保护源服务器免受对不可用对象的不必要请求默认为 5 分钟。
从问题中可以看出,最可能的解释是,对象在实际存在之前就被请求(无论出于何种原因),错误响应被缓存了几分钟,导致对象可用性出现“延迟”。但 CloudFront 没有传播延迟,因为 CloudFront 是一个拉通缓存 —— 没有什么可传播的。
您的curl
测试似乎成功了,但实际上并没有证明任何事情,显然是因为(还有其他潜在原因)您没有在请求Origin:
中包含标头curl
。这使得该curl
请求在语义上与浏览器发送的请求不同。
在评估对象是否可从缓存中提供服务时,CloudFront 不仅考虑路径。还会比较转发到源服务器的大多数标头,如果此请求要转发的标头与先前具有可用缓存响应的请求发送的标头不匹配,则不会使用缓存响应,而是将请求发送到源。其响应将与发送的标头一起缓存。
因此,有以下两个请求:
GET /object HTTP/1.1
Host: www.example.com
和
GET /object HTTP/1.1
Host: www.example.com
Origin: http://www.example.com
...(假设Origin:
标头被转发到原始服务器,因为 CORS 需要这样做)必然被视为两个不同的、本质上不相关的请求——CloudFront 不知道原始服务器是否会根据发送的请求标头修改其响应。对这两个请求的响应将分别缓存,并且每个响应都只会在响应未来匹配的请求时提供。
如果分发配置为转发 cookie 或查询字符串,则这些内容也会与缓存响应一起存储,缓存响应将仅响应与生成缓存响应的原始请求完全匹配的请求(基于所有转发的参数)。(这就是为什么不必要地转发原始服务器不需要的信息会损害您的缓存比率的原因。)
设置分布的错误缓存最小 TTL将 404 错误降至 0 可解决此问题,通过阻止缓存 404 响应。