CloudFront 如何处理对象的部分请求 (Range 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 中的范围请求
使用范围请求缓存大型对象
启用缓存后,CloudFront 不会检索或缓存大于 50 GB 的对象。如果源表示对象大于此大小(在 Content-Length
响应标头中),CloudFront 将关闭与源的连接并向查看器返回一条错误。(禁用缓存后,CloudFront 可以从源检索大于此大小的对象,然后将其传递给查看器。但是,CloudFront 不会缓存该对象。)
但借助范围请求,您可以使用 CloudFront 缓存超过最大可缓存文件大小的对象。
例 示例
-
假设某个源中具有一个 100 GB 的对象。启用缓存后,CloudFront 不会检索或缓存这样大的对象。但查看器可以发送多个范围请求以分段检索此对象,每个段小于 50 GB。
-
查看器可以发送一个带有
Range: bytes=0-21474836480
标头的请求检索第一段,发送另一个带有Range: bytes=21474836481-42949672960
的请求以检索下一段,依此类推,从而按 20 GB 的段请求该对象。 -
查看器收到所有段后,可以将这些段组合起来构建原始的 100GB 对象。
-
在此例中,CloudFront 会缓存该对象的所有 20GB 段,并且可以响应对缓存中相同段的后续请求。