写点什么

通过混沌测试发现 HTTP/2 缺陷

用户头像
卫智雄
关注
发布于: 2021 年 05 月 30 日
通过混沌测试发现 HTTP/2 缺陷

翻译自: https://www.twilio.com/blog/2017/10/http2-issues.html

摘要

虽然 HTTP/2 比 HTTP/1.x 有更多的改进,但是通过混沌测试,我们发现在某些情况下,HTTP/2 的性能比 HTTP/1 更差。


当网络出现丢包时,TCP 层的拥塞控制会对只有极少 TCP 连接的多个 HTTP/2 数据流限流。同时,由于 TCP 的重试逻辑,影响单个 TCP 连接的丢包会同时影响多个 HTTP/2 流。换句话说,线头阻塞已经从网络栈的第 7 层移至第 4 层。

背景(服务网格空间)

服务网格是云原生架构越来越常见的网络模型。通过将快速、可靠的服务间通信所需的逻辑放入 Sidecar 流程中,独立团队的开发人员可以在自己选择的技术栈中进行工作,从而获得一致的网络传输,而无需更改库或应用程序代码。


在这种进程外体系结构中,每个应用程序都通过 localhost 网络发送和接收消息,并且不知道网络拓扑。对应用程序透明,服务网格 Sidecar 可以始终如一地处理问题,例如:服务发现、负载平衡、断路、重试、加密、速率限制等。


近日,服务网格空间已经非常活跃,新的项目,如 Lyft 的 EnvoylinkerdTraefik,加上

nginxHAProxy,形成了一个日益创新的局面。


在 Twilio,我们对 Envoy 特别感兴趣,因为它有丰富的功能,包括改进的遥测功能(通过与我们已经使用的 statsd 和 LightStep 集成),先进的 AZ 感知路由功能,以及让微服务通过加密连接相互通信的一致方式。此外,Envoy 得到了谷歌的支持,最近被纳入了 CNCF,而且社区发展迅速,这让我们相信这个软件代理在未来会有更多改进。

混沌工程与测试计划

混沌工程是 Netflix 几年前创造的一个术语。简而言之,混沌工程的核心思想是主动向你的系统注入故障。这样就可以观察到系统是如何失败的,并加以改进,以便在真正的灾难来临时服务不会中断。


混沌工程原理中对混沌工程的描述:

混沌工程学是在分布式系统上进行实验的学科,目的是建立对该系统在生产中承受动荡条件的能力的信心 


对于在云中运行的分布式系统,网络延迟和数据包丢失是常见问题。为了帮助 Twilio 在面对这些问题时更加可靠和灵活,我们使用 tc 命令将不同的网络延迟和数据包丢失组合注入到我们的服务中进行混沌测试。例如:添加 0ms/10ms/25ms 网络延迟;添加 0%/1%/3% 的丢包率。


测试配置设置如下:

  • AWS 中同一可用区中的两个 c3.2xlarge 实例

  • 客户端使用 Vegeta 以 1000 qps 的速度请求 localhost Sidecar, 请求中包含 1KB POST payload 和一组真实的 HTTP Header

  • 最初,我们以 2 分钟的迭代时间运行,但由于当时的测试结果令人困惑,因此变更到 15 分钟的通宵运行时间(有关更多信息,请参见“测试结果”部分;))

  • 服务端是返回静态 1KB 正文的 nginx

  • 一些经过调整的 sysctl 配置,其他方面使用 Linux AMI 的默认值:

  • net.core.somaxconn

  • net.ipv4.tcp_fin_timeout

  • net.ipv4.ip_local_port_range

测试的 Sidecar 配置如下:

  • 无 Sidecar(即直接客户端 - 服务器)

  • HAProxy Sidecar

  • 使用 HTTP/1 的单 Envoy(类似于 HAProxy 配置)

  • 使用 HTTP/1 的双 Envoy

  • 使用 HTTP/2 的双 Envoy

  • 使用 HTTP/2 和 TLS 的双 Envoy

HTTP 请求延迟测试结果


HTTP请求延迟测试结果

在基线上,Envoy 的透明 HTTP/2 升级特性与 HAProxy 和我们的无 Sidecar 配置类似。在上图中,我们的混沌工程师没有人为添加延迟和丢包,我们可以看到,平均/中值/p95/p99 请求延迟在所有场景中都相似。尽管从 HTTP/2 中获得了额外的功能和好处,但这里的差异只是将我们的流量透明地升级到 HTTP/2 的几分之一毫秒。


然而,在我们的混沌测试场景中,结果变得更加有趣,特别是当添加 3% 的丢包率时:


在这里,我们仅看 3% 数据包丢失时的 p99 延迟,并添加不同级别的网络延迟。纵观全局,可以看到使用 HTTP/2 时,当丢包率为 3%(紫色和浅蓝色条)时,第 99% 的请求延迟始终表现更差。


这些结果让我们非常困惑。HTTP/2 不应该比 HTTP/1 更好吗?HTTP/2 是一种二进制协议,具有多路复用、持久连接和压缩标头。HTTP/2 不应该在每次测试中都击败 HTTP/1 吗?怎么可能更糟?


我们最初认为这是我们测试中的问题:也许是 AWS 云中的间歇性网络问题或我们的测试自动化中的代码错误。我们在晚上和周末反复运行测试,同时检查测试代码是否存在错误。不幸的是,测试结果非常具有可重复性。


为了寻找这个谜团的解释,我们决定更深入地研究数据。使用 Vegeta 的-dump模式,我们可以为测试期间执行的每个 HTTP 请求生成网络延迟的 CSV。然后,我们可以使用该 CSV 生成散点图,以查看基础数据中的请求延迟模式。与之前看到的通过各自聚合屏蔽数据的条形图相比,这使我们能够更清楚地了解每个网络请求发生的情况。


我们通过这些散点图发现的结果非常令人震惊!


  • 当注入 3% 丢包时,没有 sidecar 的 HTTP/1 请求延迟散点图


  • 当注入 3% 丢包时,通过 HAProxy sidecar 的 HTTP/1 请求延迟散点图


  • 当注入 3% 丢包时,通过单个 Envoy sidecar 的 HTTP/1 请求延迟散点图


  • 当注入 3% 丢包时,通过双 Envoy sidecar 的 HTTP/1 请求延迟散点图


  • 当注入 3% 丢包时,带 HTTP/2 升级的双 Envoy sidecar


  • 当注入 3% 丢包时,带 HTTP/2 和 TLS 升级的双 Envoy sidecar


  • 当存在数据包丢失时,比较 HTTP/1 与 HTTP/2 的叠加层。我们现在可以看到 HTTP/2 的 p99 请求延迟更糟。不过,我们需要解释原因。

HTTP/2 测试结果解读

上图中明显的问题是:“HTTP/2 怎么了?为什么请求延迟时间看起来是正弦曲线?”


想象以下场景:

  • HTTP/1:每个 HTTP 请求都有自己的 TCP 连接,每个 TCP 连接都独立地尝试确定自己各自的最佳 TCP 拥塞窗口 (CWND)。

  • 如果这些 TCP 连接中的任何一个遇到数据包丢失,则其他连接不受影响。

  • 如果多个 TCP 连接遇到数据包丢失,总吞吐量依然是相对大量 TCP 连接的总和。

  • HTTP/2:TCP 连接较少,是持久的。每个 TCP 连接都有多个多路复用的 HTTP/2 流。

  • 当发生丢包时,该 TCP 连接内的所有流都将遭受两个惩罚:

  • 惩罚 1:TCP 连接内的所有 HTTP 流在等待重新传输丢失的数据包时同时被阻止。即 HTTP 请求的头部阻塞已从第 7 层移至第 4 层。

  • 惩罚 2:TCP 窗口大小将急剧下降,并且所有流将同时被限流。

  • 由于 TCP 连接数也比 HTTP/1 方案少,因此总吞吐量必然低于 HTTP/1(即 N 个坏连接 > M 个坏连接,当 N > M 时)。换句话说,HTTP/2 的优势之一也是它的一大弱点。


重要的是要记住,此处确定的问题并非特定于 Envoy。在 Twilio,我们仍然将 Envoy 用作服务网格的辅助工具,因为它满足了在我们的微服务之间提供透明且一致的服务网格的业务需求(无论是通过 HTTP/1 还是 HTTP/2)。


此外,应该记住,这些测试中的延迟和丢包是用 tc 注入的。在现实世界中,人们不太可能看到 3% 的丢包持续数小时。Twilio 具有一套完善的工具来监视网络状况,并且现在我们已经了解了 HTTP/2 的弱点,对于使用 HTTP 的用例,当这些状况可能会对我们的平台产生不利影响时,我们会收到警报。此外,Envoy 通过其 statsd 和 Lightstep 集成提供了更多的指标和可见性,这增加了我们的监控工具箱。


最后,如果你正在寻找一些与这些有关的额外阅读,我强烈建议你阅读 QUIC 的 RFC 一种基于 UDP 的 HTTP/2 传输。在第 5.4 节中,来自 Google 的作者特别指出了 HTTP/2 over TCP 的这些问题,并详细介绍了他们对下一代协议的建议,即把灵活的拥堵控制转移到应用层。

结语

云服务可能具有截然不同的技术要求。想象一下,例如:营销 SaaS 与消息应用程序与流媒体视频服务。

Twilio 运营着一个需要全天候运行的全球通信网络,了解我们的服务在各种情况下的大规模运行方式对我们来说很重要。通过混沌测试,我们能够确定 HTTP/2 中的架构权衡,当网络中存在数据包丢失时,导致其性能比 HTTP/1 更差。


不过,根据您的用例,HTTP/2 可能适合您。该决定应基于全面的技术评估,其中应包括适量的混沌工程。通过这样做,您可以确保您的服务能够以卓越的可靠性和弹性大规模运行。

用户头像

卫智雄

关注

还未添加个人签名 2018.12.23 加入

还未添加个人简介

评论

发布
暂无评论
通过混沌测试发现 HTTP/2 缺陷