为啥 HTTP/2 比普通 HTTPS 慢?

Posted

技术标签:

【中文标题】为啥 HTTP/2 比普通 HTTPS 慢?【英文标题】:Why HTTP/2 is slower than plain HTTPS?为什么 HTTP/2 比普通 HTTPS 慢? 【发布时间】:2016-02-13 00:02:28 【问题描述】:

我正在评估我可以从 HTTP2 为我的网站获得的性能和奇怪的结果 - 欧洲的网站是从美国加载的:

使用 HTTP/2 - 6-7 秒 使用纯 HTTPS - 5-6 秒(大约快 1 秒)

我从 Chrome 的网络监视器中截取了屏幕截图,看起来使用 HTTP/2 时,大部分资源都是一个接一个地加载,而不是像普通 SSL 那样并行加载。

为了进行测试,我使用 Apache 2.4.17 (Win32) 涵盖的 Web 应用程序作为代理(以应用对 SSL 和 HTTP/2 协议的支持)。客户端浏览器是 Windows 7 上的 Chrome 46.0.2490.86。

捕获的网络请求如下。简短的摘要: 1.第一个——是html页面 2. 下一组 - 6 个请求 - 直接在 HTML 中声明的资源 3. 剩下的——通过脚本动态添加的资源(document/head 中的'script' 和'link/css' 标签)。

图片左边是HTTP/2, 右侧 - 通过普通 SSL 的相同员工(http2_module 已关闭)。


更新:我已经测试了支持 HTTP/2 作为反向代理的“其他东西”。它是来自http://nginx-win.ecsds.eu 的 nginx 1.9.7.1 Kitty - 原始 nginx 'for windows' 的分支。原始 nginx 中的 HTTP/2 仅在 in commercial version 可用,因此我无法尝试。而且看起来没有其他服务器实现 HTTP/2 + 反向代理 for windows,或者我找不到它们(列表 here 和 here)。

我从 Kitty 得到的结果更具误导性 - 没有像 Apache 那样的“顺序加载”资源,但是 HTTP/2 的传输速率比普通 SSL 慢两倍。最终结果是 - HTTP/2 比普通 SSL 慢得多。下面是所有这些并排的。

在所有这一切中,我只能假设性能在很大程度上取决于实现,而当前可用的实现表现得很奇怪,以得出关于 HTTP/2 的任何一致结论。

【问题讨论】:

响应标头说什么?您确定 Apache 已正确配置以发送 HTTP/2 吗?仅供参考,某些浏览器可能无法正确显示版本,请查看icing.github.io/mod_h2/howto.html。 Chrome 显示的响应标头对我没有任何用处 :(。我很确定 HTTP/2 真的“开启”,因为这个插件 (chrome.google.com/webstore/detail/http2-and-spdy-indicator/…) 显示了 HTTP/2 图标和网络行为与普通 SSL 不同 - 仅执行一次 SSL 握手。 @XtraCoder 只需右键单击 devtools 网络面板的标题,与您所附的图中相同,然后查找“协议”列。但是从图中可以看出前半部分是使用HTTP/2还是SPDY。 'Protocol' 列说它是h2,在单独的选项卡中打开chrome://net-internals/#http2 的页面,同时在另一个选项卡中加载站点显示我的站点Protocol Negotiated=h1 和'加载时活动流最多可达 5 个。 ...抱歉,在我的评论中看到错字 - 正确的措辞是 'for my site Protocol Negotiated=h2' 【参考方案1】:

所以,最后我的决定是 - HTTP/2 本身没有问题,当前可用的实现有问题。

Apache HTTPD 2.4.17 / Win32 - 有一些奇怪的“顺序加载”效果 nginx Kitty - 提供异常缓慢的传输速率 官方免费软件nginx没有内置http2模块

但是

来自kevinworthington.com的windows定制nginx Apache HTTPD 2.4.17 / linux

两者都显示出预期的性能。这是在“问题”中执行的相同测试的屏幕截图,但 Apache 反向代理托管在另一个人的 linux 计算机上。

【讨论】:

【参考方案2】:

看看这个,它是淘宝网开发的nginx的修改版,被速卖通和很多其他繁忙的网站使用。它支持开箱即用的 HTTP2,以及一些仅在商业 nginx 中可用的其他功能,例如上游控制。

http://tengine.taobao.org/

【讨论】:

不错!感谢您提供此信息。应该试试!【参考方案3】:

我们正在使用 http/2 运行最新的 nginx

nginx version: nginx/1.9.10
built with OpenSSL 1.0.2e 3 Dec 2015
TLS SNI support enabled

我们做了同样的观察。我们正在记录 $request_time 和 $upstream_time。虽然不论协议如何,upstream_time 都是相等的,但总体 request_time 是不同的:

# grep ' 443 ' access.log|grep 'HTTP/1.1'| cut -d ' ' -f 3,4 | awk 'r+=$1; u+=$2 END print r/NR; print u/NR'
0.0116887   # HTTP/1.1 request_time in seconds
0.00673473  # HTTP/1.1 upstream_time in seconds

# grep ' 443 ' access.log|grep 'HTTP/2.0'| cut -d ' ' -f 3,4 | awk 'r+=$1; u+=$2 END print r/NR; print u/NR'
0.0363673   # HTTP/2.0 request_time in seconds
0.00695812  # HTTP/2.0 upstream_time in seconds

所以 http/1.1 的整体请求时间快了三倍!由于流的原因,可能有一些东西不适用于 request_time 日志记录和 http/2。我真的不知道,但承诺是,如果两者都在 TLS 上运行,http/2 会比 http/1.1 快。

但我会进一步调查。

【讨论】:

以上是关于为啥 HTTP/2 比普通 HTTPS 慢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥分页查询比使用 Spring Data 的普通查询慢?

为啥火花延迟加载比通配符或在数组中传递文件夹慢?

为啥 oracle 存储 java 过程中的相同代码可能比普通 java 慢?

当我使用 std::algorithms 而不是普通循环时,为啥这段代码会变慢?

Linq to objects 比普通 C# 慢 20 倍。有没有办法加快速度?

为啥编译器可以比普通函数更好地优化 lambda?