这篇博文改编自 Valentin V. Bartenev 在 9 月份于旧金山举行的 nginx.conf 2015 上的演讲。
目录
0:20 | 协议概述 |
1:40 | HTTP/2 的主要功能 |
3:08 | HTTP/2 内部 – 二进制 |
4:26 | HTTP/2 内部——多路复用 |
7:09 | HTTP/2 的主要功能——标头压缩 |
8:40 | HTTP/2 的主要功能——优先级 |
10:06 | HTTP/2 的历史 |
10:16 | 测试页 |
10:52 | 测试环境 |
11:02 | DOM 加载 |
11:48 | 第一幅画 |
12:45 | 配置 |
14:20 | 问答 |
几天前,我们发布了 NGINX 的 HTTP/2 模块。 在本次演讲中,我将向您简要介绍新模块。
首先,我想揭穿有关新协议的一些谣言。
许多人认为 HTTP/2 是 HTTP/1 的优秀继承者。 我不同意这个观点,原因如下。 HTTP/2 实际上只是 HTTP/1 的另一个传输层,这并不坏,因为因此您可以使用 HTTP/2 而不必更改您的应用- 它可以使用相同的标头。 您只需在 NGINX 中打开 HTTP/2,NGINX 就会为您轻松处理所有协议内容。
但 HTTP/2 并不是魔法。 它确实有其优点和缺点。 在某些用例中它表现良好,在某些场景中它表现不佳。
您可以将 HTTP/2 视为 SPDY 的新版本,因为它基于 SPDY,并且是一种非常相似的协议。 SPDY 是 Google 几年前开发的一种协议,旨在加速网络内容传输。
NGINX 已经支持 SPDY 两年了,因此您可以使用 SPDY 模块来查看 HTTP/2 的优势。 有些人会说 HTTP/2 只是 SPDY 3.1 的完善版本。
如果您不熟悉 SPDY,我将介绍一些要点。 这些要点也适用于 HTTP/2,因为它们基本上只是相同的协议,只是细节上有一些差异。
第一个关键点是协议本身是二进制的。 我喜欢二进制协议——它们更容易编码,而且好的二进制协议具有一些性能优势。 然而,我也了解这种方法的缺点。
这是一个 HTTP/2 请求。 它看起来很酷,而且正如你所见,它非常容易调试。 不,我只是在开玩笑。 很难调试。 这是二进制协议的缺点之一。
您可能必须使用工具来解码请求或者......嗯,有时,您可能需要手动调试二进制文件,因为该工具可能会损坏,或者该工具可能不会向您显示隐藏在位中的所有细节。
幸运的是,大多数时候您只需在 NGINX 中引入 HTTP/2,而不必处理其二进制性质。 幸运的是,大多数请求将由机器处理。 机器在读取二进制协议方面比人类强得多。
HTTP/2的下一个关键点是多路复用。 HTTP/2 不会通过多个连接将响应和请求作为单独的数据流进行发送和接收,而是将它们多路复用到一个字节流或一个数据流上。 它根据不同的请求和不同的响应对数据进行切片,并且每个切片都有自己的标识和大小字段,这样端点就可以确定哪些数据属于哪个请求。
这里的缺点是,由于每个数据块都有自己的标识和自己的字段,因此除了实际数据之外,还会传输一些元数据。 因此,它有一些开销。 因此,如果您只有一个数据流,例如您正在看电影,那么 HTTP/2 不是一个好的协议,因为您得到的只是额外的开销。
多路复用有哪些好处? 多路复用的主要好处是,通过仅使用单个连接,您可以在需要创建新请求时节省使用 HTTP/1.x 进行握手所花费的所有时间。
当处理 TLS 时,这种延迟尤其令人痛苦。 这就是为什么大多数客户端现在仅通过 TLS 支持 HTTP/2。 据我所知,没有计划通过纯 TCP 支持 HTTP/2,因为它没有太多好处。 这是因为 TCP 握手并不像 TLS 握手那么昂贵,所以通过避免多个连接并不能节省太多。
HTTP/2 的下一个关键点是其标头压缩。 如果您拥有非常大的 cookie,这可以为您节省每个请求或响应的数百字节,但一般来说,大多数情况下您不会从标头压缩中受益匪浅。 因为,即使你考虑单独的请求,最终你还是会处理网络上的数据包层,而且你发送一百个字节或一百半字节并不重要,因为最终它仍然会产生一个数据包。
HTTP/2 标头压缩的缺点是它是有状态的 [编辑器– 用于存储压缩/解压缩信息的表]。 因此,对于每个连接,服务器和客户端都应该保持某种状态,这比保持 HTTP/1 连接的状态需要更多的内存。 因此,每个 HTTP/2 连接将使用更多的内存。
HTTP/2 的最后一个关键点是它的优先级机制。 这解决了多路复用引入的问题。 当你只有一个连接时,你只有一个管道,你应该仔细决定接下来要把哪个响应放入这个管道中。
在 HTTP/2 中优先级是可选的,但如果没有它,您将不会获得太多性能上的好处。 NGINX 中的 HTTP/2 模块完全支持优先级,支持基于权重的优先级和基于依赖关系的优先级。 从目前所见来看,我们目前拥有最快的 HTTP/2 实现。 这些是关于 HTTP/2 的要点。
这是一个简单的幻灯片,介绍了 HTTP/2 的历史。 相当简单。 让我们继续了解 HTTP/2 在实践中的工作原理。
为了了解 HTTP/2 在不同网络条件下的工作方式,我对典型的网页做了一些基准测试。 这只是我在 Github 上找到的一个 HTTP/2 页面。 您可以看到它有多少资源,并且可以看到每个资源有多大。 我认为它相当具有代表性的一个典型网站。
这是我的测试环境,以防您想重现测试。
这是我得到的结果。 您可以看到,我在 X 轴上模拟了不同的网络延迟,以毫秒为单位的往返时间 (RTT),然后在 Y 轴上测量了下载时间,也是以毫秒为单位。 这是测试页面加载时间,就像页面的所有资源都完全加载一样。
从图中可以看出一个明显的趋势,即对于低延迟,HTTP、HTTPS 和 HTTP/2 之间没有显著差异。 对于更高的延迟,您会发现普通 HTTP/1.x 是最快的选择。 HTTP/2 位居第二,HTTPS 是最慢的。
那么“第一幅画”的时间是怎样的呢? 在许多情况下,从用户的角度来看,它是最重要的指标,因为这是他们在屏幕上实际看到的东西。 在很多情况下,页面完全加载所需的时间并不重要,但用户看到某些内容所需的时间却很重要。
这里我们看到了相同的趋势,但测试中有趣的部分是,对于中间范围的延迟,从 30 毫秒到 250 毫秒,HTTP/2 比普通 HTTP 稍快一些,尽管差异非常小。
所以,这些就是我们的基准,现在让我们讨论如何配置 HTTP/2 和 NGINX。
事实上非常简单。 您需要做的只是将http2
参数添加到listen
指令。 这里最复杂的步骤可能是获取最新版本的 OpenSSL,因为 HTTP/2 需要 ALPN [application层协议协商] 扩展,而 ALPN 扩展仅受 OpenSSL 1.0.2 支持。
我们还为 HTTP/2 实现了 NPN [下一代协议协商],目前它可以与大多数客户端配合使用,但由于 SPDY 将于 2016 年初弃用,因此他们将不再支持 NPN。 这意味着您可以将 HTTP/2 与目前是许多 Linux 发行版的一部分的 OpenSSL 版本一起使用,但您需要记住它将在不久的将来停止工作。
所以,这就是有关为 HTTP/2 配置 NGINX 的全部内容,我的演示也到此结束。 谢谢。
[ HTTP/2 模块参考文档]
问: 您是否也会在上游支持 HTTP/2,还是仅在客户端支持 HTTP/2?
一个: 目前,我们仅支持客户端的 HTTP/2。 您无法使用proxy_pass
配置 HTTP/2。[编辑 – 在这篇文章的原始版本中,这句话被错误地转录为“您可以使用proxy_pass
配置 HTTP/2。” 对于由此造成的任何混淆,我们深表歉意。 ]
但是 HTTP/2 在后端有什么意义呢? 因为正如你从基准测试中看到的那样,HTTP/2 对于低延迟网络(例如上行连接)没有太大的好处。
此外,在 NGINX 中您有keepalive模块,并且您可以配置 keepalive 缓存。 HTTP/2 的主要性能优势在于消除额外的握手,但如果你已经使用 keepalive 缓存实现了这一点,那么上游就不需要 HTTP/2。
准备好在您的环境中尝试使用 NGINX Plus 的 HTTP/2 了吗? 立即开始您的30 天免费试用或联系我们讨论您的用例。
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”