Amazon-Cloudfront

Amazon CloudFront CORS 特定延遲

  • April 20, 2016

我在提供 CORS 請求之間遇到了延遲,但可以正常處理直接請求。我正在使用它通過 HTTP 分發媒體流,因此減少啟動延遲非常重要。

從通過 CloudFront 分配(通過來自瀏覽器或 curl 的直接請求)提供媒體清單到來自我們網站上的播放器的 CORS 請求返回成功之間大約有 90-180 秒。我已經在 CloudFront 分配中啟用了 OPTIONS 請求轉發,並且也包含了 OPTIONS 請求的結果。我在下面的 Chrome 開發工具中包含了 curl 請求的結果和網路選項卡的相應結果。請注意,這些請求是在 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 請求===

顯示收到的 404 錯誤的 Chrome 開發工具網路選項卡的螢幕截圖

===選項請求===

*   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

不知所措地看到我的配置中的錯誤,任何幫助將不勝感激。

預設情況下,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 或查詢字元串,這些也將與記憶體響應一起儲存,這些響應將僅在響應與生成記憶體響應的原始請求完全匹配的請求時提供 - 基於所有轉發參數。(這就是為什麼不必要地轉發你的源伺服器不需要的資訊會損害你的記憶體率。)

將分發的404 錯誤的錯誤記憶體最小 TTL設置為 0 可以通過阻止記憶體 404 響應來解決此問題。

引用自:https://serverfault.com/questions/771047