Назад | Перейти на главную страницу

Задержка для Amazon CloudFront CORS

У меня возникла задержка между обслуживанием запросов CORS, но прямые запросы обслуживаются нормально. Я использую это для распределения медиапотоков через HTTP, поэтому очень важно уменьшить задержку запуска.

Примерно 90–180 секунд между моментом, когда манифест мультимедиа доступен через распространение CloudFront (посредством прямого запроса из браузера или curl), и когда запросы CORS от плеера на нашем веб-сайте возвращают успех. Я включил пересылку запросов OPTIONS в раздаче CloudFront и также включил результаты запроса 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 Dev, показывающий полученную ошибку 404

=== ОПЦИИ Запрос ===

*   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 или строк запроса, они также сохраняются вместе с кешированным ответом, который будет обслуживаться только в ответ на запросы, которые точно соответствуют исходному запросу, который сгенерировал кешированный ответ - на основе всех переадресованные параметры. (Вот почему излишняя пересылка информации, которая не нужна вашему исходному серверу, повредит коэффициенту вашего кеширования.)

Настройка раздачи Ошибка кеширования Минимальный TTL для 404 ошибок до 0 решает эту проблему, предотвращая кеширование 404 ответов.