[翻译]Dropbox Web 服务启用 HTTP/2:经验和观察

Haowei Yuan | 2016年5月11日

最近,为了启用 HTTP/2,我们 Dropbox 的流量团队升级了前端的 Nginx 服务器。本文将分享我们迁移到 HTTP/2 的过程中的体验和新发现。整个过程较为顺利,但还是有发现一些坑,也许对大家有帮助。

背景:HTTP/2 与 Dropbox Web 服务架构

HTTP/2 (RFC 7540) 是 HTTP 协议的新的大版本。它基于 SPDY 协议,而且相比于 HTTP/1.1 提供了好多性能优化。这些优化包括:更高效的报头压缩、Server Push、多路复用等等。至今,过半浏览器已经支持HTTP/2

Dropbox 使用开源的 Nginx 做 SSL 终结前端和为流量提供七层负载均衡。升级前,我们的前端服务器跑的是基于 Nginx 1.7 的软件,并且支持 SPDY。另一个升级的动力来自,虽然 Chrome 目前既支持 SPDY 也支持 HTTP/2 ,但他们很快会在5月15日 放弃SPDY支持。如果那时不支持 HTTP/2 ,我们的 Chrome 用户就会从 SPDY 降级到使用 HTTP/1.1。

HTTP/2 升级步骤

升级 HTTP/2 对我们来说是个直截、而且平滑的切换。Nginx 1.9.5 增加了 HTTP/2 模块(也由 Dropbox 共同协助),并默认弃用了 SPDY 支持。我们当时就决定升级到 Nginx 1.9.15,即那时的最新稳定版。

用 Nginx 升级 HTTP/2 只需对配置文件做小小的改动。只需将 http2 关键字增加到 listen 指令后面。因为我们之前启用了 SPDY,所以只需将 spdy 替换成 http2

升级前  (SPDY): listen A.B.C.D:443 ssl spdy; 
升级后 (HTTP/2): listen A.B.C.D:443 ssl http2;

当然,您或许会需要浏览完整的 Nginx HTTP/2 配置选项,好针对某些特定的场景做优化。

部署方面,我们首先在小流量机器上启用 HTTP/2 了一个星期,同时线上依然使用 SPDY。在确定了正确性,并且评估了性能之后,HTTP/2 才全量启用。

http2 transition

从 SPDY 到 HTTP/2 的平滑切换 (60 分钟的流量数据)

上图展示了从 SPDY 到 HTTP/2 的平滑切换。余留的 HTTP/1.1 连接在图中没有显示。我们分别在大约第 23 、第36 和第 50 分钟,逐步将所有前端 Web 服务器启用了 HTTP/2。在此之前,在线连接既有小流量机器的 HTTP/2 流量,也有线上机器的 SPDY 流量。如您所见,基本上所有 SPDY 连接着的客户端最终都转移到了 HTTP/2 上。

观测

在小流量机器上启用了 HTTP/2 后,我们紧密地监测着性能。观察得到的既有代表 HTTP/2 的高效性能的数据,也有一些由于 HTTP/2 的实现还较新而产生的坑。

性能提升

我们观测到流入带宽开销显著降低,这是由更高效的报头(Header)压缩(HPACK)带来的。

traffic bandwidth

降低的流入带宽开销 (24 个小时的流量数据)

上图展示了HTTP/2 只在小流量机器上启用时,小流量和线上机器平均(每台机器)的带宽开销。每一台小流量机器和线上机器都从负载均衡服务器上拿到了几乎一样大的流量。可以看到,启用 HTTP/2 以后,入网带宽流量降低很显著(差不多50%)。值得一提的是,虽然我们之前在所有小流量和线上机器启用了 SPDY,但并没有开启 SPDY 的报头压缩,因为有一个相关联的安全问题 (CVE-2012-4929 也就是 CRIME)存在。至于出网流量,则并没有显著的改变,因为报头在响应流量中通常只占很小一部分。

一些坑

更新: POST 请求延迟增加和 REFUSED_STREAM 错误h的问题在最近的 Nginx 1.11.0 版本 已经得到了修正。  变更后新的 P50 请求延迟的数据图在文末附上。

POST请求延迟提高了。当我们在小流量机器上启用 HTTP/2 时,发现延迟中位数上升了。下图展示了小流量和线上机器之间的 P50 请求延迟(P50 request latency,即 50% 的请求延迟比这个时间短,下同)。经过调查这个问题,我们发现,延迟是由 POST 请求产生的。更深入研究之后,这个行为看起来是归咎于 Nginx 1.9.15 的某些实现而产生的。相关的讨论可以在 Nginx 邮件列表 中找到。

request latency

P50 响应延迟提高 (24 个小时的流量数据)

注意在此看到的 P50 请求延迟提高的百分比(大约变成 1.5 倍)取决于特定的流量负荷。在大部分情况下,增加的负担对我们来说大约是一个 RTT(round trip time,往返延时) 那么多,并没有太影响我们的关键性能。然而,如果您的流量负荷包含许多小的、对延迟敏感的 POST 请求,那么增加的延迟时间是您考虑是否升级到 Nginx 1.9.15 的重要考虑因素。

为所有内容都启用 HTTP/2 要小心,尤其是当您不能控制客户端的时候。由于 HTTP/2 还是比较新,从我们的经验来看,一些客户端/库和服务器的实现还不是兼容得很好,例如:

  • 使用 Nginx 1.9.15,如果客户端试图在获知帧(Frame)的连接设置(SETTING)之前发送 数据(DATA)帧,POST 请求就会得到 REFUSED_STREAM 错误。我们发现 Swift SDK 存在该问题。值得一提的是,监测 Nginx 错误日志在部署过程中至关重要,而观察到这个错误信息需要把错误日志的记录严重等级提升到 INFO 。
  • Chrome 未能正确处理带有 NO_ERROR 的 RST_STREAM 帧,引发了一些与 Nginx 1.9.14 之间的问题 (Chromium Issue #603182)。 Nginx 1.9.15 提供了该问题的临时解决方案。
  • 在没有窗口空间时,Nghttp2 不会发送 END_STREAM 信号, 这个问题也在前述的 Nginx 邮件列表 中有讨论。

由于我们的 API 用户可能涉及到各种第三方 HTTP 库,我们需要进行更充分的测试才能为我们的 API 开启 HTTP/2 支持。

调试工具

CloudFlare 已经有一篇 总结得很好的 HTTP/2 调试工具总结。另外,我们发现 Chrome 的 Net-internals 工具 (Chrome 中通过 chrome://net-internals/#http2 可以访问) 也很有用。下图是当开启一个新的指向 www.dropbox.com 的会话时,Net-internals 工具记录帧的传输的截屏。

开启一个新的 HTTP/2 会话时 Net-internals 的截屏

总之,我们平滑的迁移到了 HTTP/2。以下是本文的内容的再次概括:

  • Nginx 中开启 HTTP/2 很简单。
  • 由于报头压缩的存在,入网带宽流量开销显著会降低。
  • 由于 Nginx 1.9.15 的某些 HTTP/2 实现,POST 请求的延迟会提高。
  • 当现有实现的兼容性还不够全面的时候,为所有内容都开启 HTTP/2 要小心。
  • 小流量验证和 Nginx 错误日志检查可以帮助尽早发现潜在的问题。

我们希望本文对有兴趣给服务器开启 HTTP/2 和对网络感兴趣的人有帮助。也欢迎收到您从下方的评论框给予的反馈。

更新: POST 请求延迟的增加和 REFUSED_STREAM 错误的问题在最近的 Nginx 1.11.0 版本 已经得到了修正。 下图展示了小流量机器变更了之后, P50 请求延迟比例 (小流量机器和线上机器延迟时间的比例) 降低了。要注意图中线上机器的 P50 请求延迟在之前为了支持 HTTP/2 升级到 Nginx 1.9.15 的时候有所增加。

Reduced P50 latency

变更之后 P50 请求延迟比例降低了 (4 个小时的流量数据)

贡献者: Alexey Ivanov, Dmitry Kopytkov, Dzmitry Markovich, Eduard Snesarev, Haowei Yuan, and Kannan Goundan


评论翻译

Haowei Yuan
由于有人感兴趣,我们在小流量机器上启用 HTTP/2 以后,P95 请求延迟比例(小流量机器和线上机器的比值)保持在接近 1.0 。

参考文档


原文地址:enabling-http2-for-dropbox-web-services-experiences-and-observations/
首发于众成翻译Dropbox Web 服务启用 HTTP/2:体验和观测

发布者

袁 源

我是袁源,职业是前端开发

关注我的新浪微博

8 thoughts on “[翻译]Dropbox Web 服务启用 HTTP/2:经验和观察”

发表评论

电子邮件地址不会被公开。 必填项已用*标注