HTTP/2 和文件下载

Pur*_*aze 5 file cdn download http-1.1 http2

我们提供文件托管解决方案。我们的客户是最终用户,他们通过 HTTP 1.1 协议访问我们的服务器并下载文件。这些客户端基本上是软件系统或 CDN,他们使用软件库下载我们的文件。没有人类用户访问我们的系统。我们还提供使用 HTTP/1.1 range-header 等的部分文件下载选项。客户端系统还使用多个线程通过跨块拆分来下载大文件。

我想检查一下,如果我们向我们的服务器开放 HTTP/2.0 协议是否会有真正的好处?既然我们的客户端系统已经能够使用多线程下载我们的文件,那么 HTTP/2.0 多路复用会增加任何真正的好处吗?

谢谢

sbo*_*det 12

HTTP/2 文件下载比 HTTP/1.1 慢一些,主要有两个原因:帧开销和流量控制

在 HTTP/1.1 中,如果您使用Content-Length分隔下载,则下载的唯一字节是内容字节。然而,在 HTTP/2 中,每个DATA帧携带 9 个额外字节作为帧头。正常最大帧大小为 16384 字节,这是一个很小的开销,但它存在。

HTTP/2 流量控制可能会导致速度变慢。客户端必须确保扩大默认会话和流控制窗口,默认情况下均为 65535 字节。

HTTP/2 的工作方式是服务器为每个 HTTP/2 会话(连接)和该会话中的每个流保留一个发送窗口。当下载开始时,服务器有权仅发送发送窗口允许的字节数,用于该流或该会话,以先用完的为准。然后它必须等待客户端发送WINDOW_UPDATE帧,补充流和会话流控制窗口,告诉服务器客户端已准备好接收更多数据。

对于像默认窗口这样的小窗口,由于客户端和服务器之间的网络延迟,这种机制可能会降低下载性能,特别是如果它是天真地实现的。服务器会在大部分时间停止等待客户端发送 aWINDOW_UPDATE以便服务器可以发送更多数据。

多路复用有双重作用。虽然它允许同时启动许多文件的下载(可能比 HTTP/1.1 多得多的文件,这可能受到它只能打开较少数量的连接这一事实的限制),但为每个流下载的数据也是如此有助于减少会话发送窗口。每个流可能仍然有一个未耗尽的发送窗口(因此它可以发送更多数据),但会话窗口已耗尽,因此服务器必须停止。流相互竞争以消耗会话发送窗口。服务器实现也很重要,因为它必须正确地交错来自多个流的帧。

话虽如此,HTTP/2 仍然有可能实现与 HTTP/1.1 相同的目标,前提是您拥有非常先进的客户端和服务器实现,并且您有足够的调整旋钮来控制关键参数。

理想情况下,在客户端:

  • 控制会话和流初始流量控制窗口的能力
  • 一个很好的实现,WINDOW_UPDATE在服务器仍在下载时向服务器发送帧,这样服务器就不会停止;这可能需要根据带宽延迟产品的自调整功能(类似于 TCP 所做的)

理想情况下,在服务器上:

  • 从同一会话的多个流中正确交错帧的能力(例如,避免下载第一个流的所有帧,然后下载第二个流的所有帧,等等,而是第一个流的一个帧,然后是第一个流的一个帧第二个流,然后又是第一个流的一帧,等等)

【免责声明,我是Jetty的 HTTP/2 维护者】

Jetty 9.4.x 支持上述所有功能,因为我们与社区和客户合作以确保 HTTP/2 下载尽可能快。

我们实施适当的交错的服务器上,而码头的HttpClient,并HTTP2Client分别提供高电平和低电平的API来处理HTTP和HTTP / 2请求。流控制在其中实现BufferingFlowControlStrategy并允许WINDOW_UPDATE在发送帧时进行调整(尽管还不是动态的)。客户端还可以选择配置初始流控制窗口。Jetty 中的一切都是可插拔的,因此您可以编写更高级的流控制策略。

即使您不使用 Java 或 Jetty,也要确保剖析(或编写)您在客户端和服务器上使用的库,以便它们提供上述功能。

最后,您需要尝试和衡量;通过适当的 HTTP/2 实现和配置,复用效果应该发挥作用,从而增加并行度并降低客户端和服务器上的资源利用率,这样您将比 HTTP/1.1 具有优势。