如何 CloudFront 处理对象的部分请求(范围 GET) - Amazon CloudFront
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

如何 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 部分中的每一个,并且可以响应缓存中同一部分的后续请求。