HTTP/2 流与 HTTP/1.1 连接

Posted

技术标签:

【中文标题】HTTP/2 流与 HTTP/1.1 连接【英文标题】:HTTP/2 streams vs HTTP/1.1 connections 【发布时间】:2016-09-10 01:07:34 【问题描述】:

如果我们忽略在 HTTP/1.1 中创建新连接的开销,是否存在连接性能优于 HTTP/2 流的情况?

我对页面加载时间进行了一些性能测试,我注意到 HTTP/1.1(https) 在响应较大的请求方面的性能优于 HTTP/2。然后当我开始提高并发级别时,HTTP/2 开始表现得更好。换句话说,HTTP/2 开始提供更好性能的并发级别随着响应消息的大小而上升。

对我来说,为什么 HTTP/2 随着并发级别的增加而开始表现得更好。但我不明白为什么返回较大响应的请求需要更高的并发性才能显示比返回较小响应的请求更好的性能。

添加一些测试结果。

服务器:码头, 浏览器:铬, 延迟:100ms, 带宽:100 兆位

我从一个网页中检索了 X 个 100KB 的图像,其中 X 从 1 到 500 不等。

此外,加载 100 个 1MB 图像导致 HTTP/2 比 HTTP/1.1 慢 50%。

【问题讨论】:

用一些测试结果和环境更新了问题 【参考方案1】:

HTTP/2 使用流量控制来避免端点分配无限量的内存。

通常浏览器会发送一个WINDOW_UPDATE 帧来扩大其会话接收流控制窗口(默认情况下只有 65535 个八位字节),因此服务器会话发送流控制窗口。

关于 HTTP/1 流量控制是比较 HTTP/1 和 HTTP/2 下载时要考虑的额外变量。

服务器可能会开始写入数据,耗尽其流或会话发送流控制窗口并停止写入,直到客户端消费完数据并向服务器发送WINDOW_UPDATE 帧。

使用 HTTP/2,流或会话可能会因为流量控制而停止,而在 HTTP/1 中不会发生这种情况。

Jetty 在这种情况下是高度可配置的。

首先,您可以监控会话或流是否已停止。这通过 FlowControlStrategy 实现 (AbstractFlowControlStrategy.get[Session|Stream]StallTime()) 中的 JMX 公开。

如果您尝试使用 Jetty 的 HTTP/2 客户端而不是浏览器执行测试,您还可以通过调整 BufferingFlowControlStrategy.bufferRatio 参数来调整 when 以发送 WINDOW_UPDATE 帧。 越接近0.0,越早发送WINDOW_UPDATE帧,越接近1.0,越晚发送WINDOW_UPDATE帧。

测试还应该报告客户端和服务器之间的网络往返,因为这会影响(通常支配)WINDOW_UPDATE 帧从客户端到服务器所花费的时间。

在完美下载中,您希望客户端足够早地发送WINDOW_UPDATE 帧,以便在WINDOW_UPDATE 帧到达服务器时,服务器尚未消耗流/会话发送流控制窗口,并且因此它将始终打开发送流控制窗口并且永远不会停止。

我不知道何时浏览器发送WINDOW_UPDATE 帧的可配置性如何,因此对于大型下载,这可能会影响下载速度。

您希望密切关注客户端重新配置其会话和流接收流控制窗口的大小,以及何时发送WINDOW_UPDATE 帧。

最后,另一个可能影响下载速度的参数是使用的 TLS 密码。 您的 HTTP/1 连接协商的密码可能比 HTTP/2 协商的密码弱得多(因为 HTTP/2 只需要非常强的密码),因此即使是非停滞的 HTTP/2 下载也比 HTTP/1 慢因为加密速度变慢了。

【讨论】:

以上是关于HTTP/2 流与 HTTP/1.1 连接的主要内容,如果未能解决你的问题,请参考以下文章

再见 HTTP 1.1,怎样把网站升级成 HTTP 2?

详解HTTP协议版本(HTTP/1.01.12.03.0区别)

详解HTTP协议版本(HTTP/1.01.12.03.0区别)

计算机网络 ---- HTTP/1.1HTTP/2HTTP/3演变过程

计算机网络 ---- HTTP/1.1HTTP/2HTTP/3演变过程

在纯文本连接器上启用 HTTP/2