file - HTTP/2和文件下载

标签 file download cdn http2 http-1.1

我们提供文件托管解决方案。我们的客户是最终用户,他们通过HTTP 1.1协议(protocol)访问我们的服务器并下载文件。这些客户端基本上是软件系统或CDN,它们使用软件库下载我们的文件。没有人类用户访问我们的系统。我们还提供使用HTTP/1.1范围标题等进行部分文件下载的选项。客户端系统还通过使用多个线程拆分成多个块来下载大文件。
我想检查一下,如果我们向服务器开放HTTP/2.0协议(protocol)是否会有真正的好处?由于我们的客户端系统已经具有使用多个线程下载文件的功能,HTTP/2.0复用是否会带来真正的好处?
谢谢

最佳答案

HTTP/2文件下载比HTTP/1.1慢一点,主要有两个原因:帧开销和flow control

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

HTTP/2流控制是造成可能的速度下降的最大原因。
客户端必须确保扩大默认的 session 和流流控制窗口,默认情况下均为65535字节。

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

对于诸如默认窗口之类的小窗口,此机制可能会由于客户端和服务器之间的网络延迟而导致下载性能下降,特别是如果幼稚地实现该机制。
服务器大部分时间将处于等待状态,以等待客户端发送WINDOW_UPDATE,以便服务器可以发送更多数据。

复用扮演双重角色。虽然它允许并发启动许多文件的下载(可能比HTTP/1.1多得多的文件,但实际上它只能打开较少数量的连接,因此可能受到限制),但也确实为每个流下载了数据有助于减少 session 发送窗口。每个流可能仍具有未耗尽的发送窗口(因此它可以发送更多数据),但是 session 窗口已耗尽,因此服务器必须停止。流彼此竞争以消耗 session 发送窗口。服务器实现也很重要,因为它必须正确地交错多个流中的帧。

话虽如此,只要您对客户端和服务器都具有相当高级的实现,并且具有足够的调整旋钮来控制关键参数,HTTP/2仍然有可能实现与HTTP/1.1的奇偶校验。

理想情况下,在客户端上:

  • 控制 session 和流初始流控制窗口的能力
  • 一个很好的实现,可以在服务器仍在下载时将WINDOW_UPDATE帧发送到服务器,以使服务器永不停止。这可能需要自调整功能,具体取决于bandwidth-delay product(类似于TCP的功能)

  • 理想情况下,在服务器上:
  • 能够正确交错来自同一 session 的多个流的帧(例如,避免下载第一个流的所有帧,然后下载第二个流的所有帧,等等,但是先下载第一个流的一个帧,然后再下载一个帧)第二个数据流,然后是第一个数据流的一帧,依此类推。)

  • [免责声明,我是Jetty的HTTP/2维护者]

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

    我们在服务器上实现了适当的交织,Jetty的HttpClientHTTP2Client分别提供了高层API和底层API,以处理HTTP和HTTP/2请求。流控制在 BufferingFlowControlStrategy 中实现,并允许调整WINDOW_UPDATE帧的发送时间(尽管尚未动态发送)。
    客户端还具有用于配置初始流控制窗口的选项。
    Jetty中的所有内容都是可插拔的,因此您可以编写甚至更高级的流控制策略。

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

    最后,您需要尝试测量;通过正确的HTTP/2实现和配置,多路复用效果应发挥作用,因此提高了并行度并降低了客户端和服务器上的资源利用率,因此您将拥有优于HTTP/1.1的优势。

    关于file - HTTP/2和文件下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44019565/

    相关文章:

    PHP:读取 config.ini 以使用 file() 排列

    ORACLE - 将程序/包导出到文件

    angularjs - 二进制文件损坏 - 如何使用 AngularJS 下载二进制文件

    javascript - 如何在 XHTML 中添加 jQuery CDN 回退?

    cdn - 是否有任何 CDN 允许重写请求 URI,以便客户端路由与浏览器刷新配合得很好?

    python - 解决类型错误 : 'file' object has no attribute '__getitem__'

    Android - 基本下载进度文本

    javascript - 自动下载行为和后退按钮问题

    php - 将外部产品图片添加到 opencart

    linux - Bash 将 ls 错误写入文件