如何 CloudFront 处理对象的部分请求(范围 GET) - Amazon CloudFront

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

如何 CloudFront 处理对象的部分请求(范围 GET)

对于大型对象,查看器(Web 浏览器或客户端)可能做出多个 GET 请求并使用 Range 请求标头以较小的段下载对象。字节范围的这些请求,有时也被称为 Range GET 请求,提高了部分下载的效率和恢复部分失败的传输。

CloudFront 收到Range GET请求时,它会检查接收请求的边缘站点中的缓存。如果该边缘位置的缓存已经包含整个对象或对象的请求部分,则 CloudFront 立即从缓存中提供请求的范围。

如果缓存不包含请求的范围,则将请求 CloudFront 转发到源。(为了优化性能,请求的范围 CloudFront 可能大于客户端在中请求的范围Range GET。) 接下来会发生的操作取决于源是否支持 Range GET 请求:

  • 如果源站支持Range GET请求:它会返回请求的范围。 CloudFront 为请求的范围提供服务,还会将其缓存以备将来的请求使用。(与许多 HTTP 服务器一样,Amazon S3 支持 Range GET 请求。)

  • 如果源不支持Range GET请求:它将返回整个对象。 CloudFront 通过发送整个对象来处理当前请求,同时还会将其缓存以备将来的请求。将整个对象 CloudFront 缓存到边缘缓存中后,它会通过提供Range GET请求的范围来响应新的请求。

无论哪种情况,只要第一个字节从源端到达,就会 CloudFront 开始向最终用户提供请求的范围或对象。

注意

如果查看者发出Range GET请求并且源返回Transfer-Encoding: chunked,则将整个对象 CloudFront 返回给查看者,而不是请求的范围。

CloudFront 通常遵循标Range头的 RFC 规范。但是,如果您的 Range 标头不遵守以下要求,CloudFront 将返回 HTTP 状态码 200 与完整的对象,而不是状态码 206 与指定的范围:

  • 范围必须列按升序排列。例如,100-200,300-400 是有效的,300-400,100-200 是无效的。

  • 范围不能重叠。例如,100-200,150-250 是无效的。

  • 所有范围的规范必须有效。例如,您不能指定负值作为范围的一部分。

有关 Range 请求标头的更多信息,请参阅 RFC 7233 中的范围请求,或者 MDN Web Docs 中的范围

使用范围请求缓存大型对象

启用缓存后, CloudFront 不会检索或缓存大于 50 GB 的对象。当原点表示对象大于此大小时(在Content-Length响应标头中),则 CloudFront 关闭与原点的连接并向查看者返回错误。(禁用缓存后, CloudFront 可以从原点检索大于此大小的对象并将其传递给查看者。 但是, CloudFront 不会缓存对象。)

但是,对于范围请求,您可以使用 CloudFront 缓存大于最大可缓存文件大小的对象。例如,假设某个源中具有一个 100GB 的对象。启用缓存后, CloudFront 不会检索或缓存这么大的对象。但查看器可以发送多个范围请求以分段检索此对象,每个段小于 50 GB。例如,查看器可以发送一个带有 Range: bytes=0-21474836480 标头的请求检索第一段,发送另一个带有 Range: bytes=21474836481-42949672960 的请求以检索下一段,依此类推,从而按 20GB 的段请求该对象。查看器收到所有段后,可以将这些段组合起来构建原始的 100GB 对象。在这种情况下, CloudFront 缓存对象的 20 GB 部分中的每一个,并且可以响应缓存中同一部分的后续请求。