ITPUB

性能比拼: HTTP/2 vs HTTP/3

来源:旅途散记(翻译)

本内容是对知名性能评测博主 Anton Putra HTTP/2 vs. HTTP/3 performance benchmark[1] 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准

在本内容中,我们将比较 HTTP/2 和 HTTP/3 协议。

我们将使用 Terraform 和 Ansible 在 Google Cloud Platform (GCP) 中创建基础设施,然后从源代码配置和编译 Nginx。

对于第一个测试,我们将使用一个包含大量图片的普通 HTML 页面。

对于第二个更贴近现实的测试,我使用了我自己的网站,该网站包含大量图片且 JavaScript 较重。

为了自动化测试,我们将使用 Playwright Node.js 框架和 Chromium 无头浏览器。当然,我们还会从测试中将指标推送到 Prometheus Pushgateway。

图片

现在,您可以使用例如 Lighthouse 来测量很多东西,但为了简化这个测试并使其简短,我们将使用 PerformanceNavigationTiming API 接口,并且只测量页面加载时间(从 startTime 到 loadEventEnd)。通过使用相同的 API,您可以获取浏览器加载过程中不同事件的更详细指标。

图片

当然,为了并排可视化指标,我们将使用 Grafana 并从 Prometheus 拉取指标。

这两种协议之间的主要区别在于 HTTP/3 使用 QUIC 传输协议,该协议基于 UDP。因此,当您创建防火墙时,不要忘记打开 443 UDP 端口,而不仅仅是 TCP 端口。

图片

对于 GCP 中或多或少较大的项目,您通常会在一个专用的宿主项目(host project)中创建共享 VPC(Shared VPC),并将其与其他服务项目(service projects)共享。要配置防火墙,您可以使用 CIDR 范围、网络标签,或者推荐的选项是创建一个专用的服务账户,并将其用作源或目标。

图片

现在,检查协议最简单的方法是点击“检查”(inspect)并打开网络(Network)选项卡。对于 HTTP/3,您应该看到 h3,对于 HTTP/2 则是 h2。

图片

不幸的是,Nginx 的 HTTP/3 实现尚未进入主线(mainline)分支。如果您想尝试一下,需要克隆这个分支或下载相应的 tar 压缩包。如您所见,它正处于积极开发中。

图片

下一步,您需要下载一些用于编译 Nginx 的依赖项,包括其中一个 OpenSSL 实现。在这个案例中,我使用的是 LibreSSL。然后我们配置 Nginx 并运行 make 进行编译。接着复制一些文件并启动 Nginx。

图片

您可以在 我的 GitHub 仓库中[2] 找到源代码。您也可以使用 Ansible 动态清单(dynamic inventory)在 GCP 中运行 Playbook。在 Playbook 中,您可以将虚拟机的标签(labels)用作 Ansible 的主机组(host groups)。

对于 HTTP/2,我们需要显式启用它,并且仅为了测试目的,在浏览器端禁用缓存。在 HTTP/2 和 HTTP/3 中,我们都使用 TLSv1.3,因为 HTTP/3 依赖于它。

图片

对于 HTTP/3,我们使用 http3 指令以及 reuseport。它使得内核可以为每个套接字拥有更多的套接字监听器。升级到 HTTP/3 的主要机制是使用以下头部(headers)。这也取决于具体实现。例如,h3-27 是 HTTP/3 协议的一个草案版本。

正如我提到的,为了运行测试,我们将使用 Playwright 框架和 Prometheus 客户端将指标推送到 Pushgateway。这个测试脚本写得不是很漂亮,但能完成工作。启动一个新的无头 Chrome 浏览器实例,然后加载页面,将指标发送到 Pushgateway 并退出。然后根据需要重复此过程多次。

图片

在这个项目中,我使用的是 GCP 的 us-central-1 区域,而我本人实际位于加利福尼亚州,这只是为了给您提供一个关于延迟的参考。

要记录指标,您还需要有 Prometheus、Pushgateway 和 Grafana。要运行它们,请使用 docker-compose up 命令。

在我们运行测试之前,让我向您展示第一个页面的样子。这是一个包含大量图片的简单页面。

图片

好了,让我们开始运行测试。您可以立即注意到,加载这个简单页面时,HTTP/3 版本比 HTTP/2 花费的时间稍微多一点。

不仅仅是我注意到了 Nginx HTTP/3 实现的性能下降。您可以找到其他的基准测试。现在,正如我所说,Nginx 支持 HTTP/3 还处于非常早期的阶段。我相信他们会改进性能并将其移至主线分支。届时我会再次进行测试。

图片

为了确认我们确实使用了 HTTP/3 协议,您可以检查 Nginx 的访问日志。您应该能找到 HTTP/3 版本信息。

图片

对于第二个测试,我使用了我自己的个人网站,其中包含大量的 JavaScript 和图片。让我们开始运行它。不幸的是,页面加载时间的差异甚至更大了。

图片

请记住,由于它正处于积极开发中,每个新的提交(commit)都可能影响性能。如果您想在生产环境中使用它,您应该亲自进行测试,或者等到它成熟并迁移到 Nginx 的主线和稳定分支。

图片
参考资料
[1] 

HTTP/2 vs. HTTP/3 performance benchmark: https://www.youtube.com/watch?v=-0yu_zOFilg

[2] 

我的 GitHub 仓库中: https://github.com/antonputra/tutorials/tree/main/lessons/148

Image