我们提供文件托管解决方案。我们的客户是最终用户,他们通过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的奇偶校验。
理想情况下,在客户端上:
WINDOW_UPDATE
帧发送到服务器,以使服务器永不停止。这可能需要自调整功能,具体取决于bandwidth-delay product(类似于TCP的功能)理想情况下,在服务器上:
[免责声明,我是Jetty的HTTP/2维护者]
Jetty 9.4.x支持上述所有功能,因为我们已经与社区和客户合作,以确保HTTP/2下载尽可能快。
我们在服务器上实现了适当的交织,Jetty的
HttpClient
和HTTP2Client
分别提供了高层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/