Dropbox web 服务启用 HTTP/2 的相关经验分享(译)
ZMHOde
8年前
<p><img src="https://simg.open-open.com/show/c06741c169e00530530ae4b7124ace6a.png"> 在 Dropbox ,我们的运维团队于近日升级了前端 Nginx 服务器开启了 web 服务的 HTTP/2 支持。在本篇文章中,我们将就此次 HTTP/2 的升级过渡,分享我们的一些经验以及相关发现。总体来说此次升级还算平滑,然而依旧踩了很多的“坑”碰到了不少注意事项,希望会对他人有所帮助。</p> <h3>背景:HTTP/2 以及 Dropbox web 服务架构</h3> <p>HTTP/2( <a href="/misc/goto?guid=4959673434023787761" rel="nofollow,noindex">RFC 7540</a> )是新一代的 HTTP 协议版本,它基于 <a href="/misc/goto?guid=4959673434114267197" rel="nofollow,noindex">SPDY</a> ,相比于 HTTP/1.1 提供了数项性能优化。这些优化包括:更高效的首部压缩(Header compression)、服务端推送(Server push)、同一连接上的流复用(Stream multiplexing),等等。如今, <a href="/misc/goto?guid=4958878844561335274" rel="nofollow,noindex">HTTP/2 已经被大部分浏览器所支持</a> 。</p> <p>Dropbox 使用开源的 Nginx 处理 SSL 连接并且对 web 流量进行七层的负载均衡。在升级之前我们前端的 Web 服务器运行的是 Nginx 1.7 并且支持 SPDY。另一个顾虑则是 Chrome 虽同时支持 SPDY 以及 HTTP/2 ,但是官方将会 <a href="/misc/goto?guid=4958985384011826086" rel="nofollow,noindex">在 5 月 15 起,停止对 SPDY 的支持</a> 。如果那时我们仍然不能提供 HTTP/2 的支持的话,意味着我们的 Chrome 客户将会从使用 SPDY 回退到 HTTP/1.1。</p> <h3>HTTP/2 升级过程</h3> <p>整个 HTTP/2 升级过程很平稳,Nginx 1.9.5 增加了 HTTP/2 模块(由 Dropbox 联合赞助)默认抛弃了对 SPDY 的支持。就我们而言,我们打算升级到 Nginx 1.9.15 ,也就是最新的 stable 版本。</p> <p>Nginx 的升级包括基本的配置文件修改,启用 HTTP/2 的支持,需要将 http2 指令添加到 listen 字段。就我们而言,因为之前已经开启 SPDY,所以只需将 spdy 替换成 http2 就行了。</p> <pre> Before (SPDY): listen A.B.C.D:443 ssl spdy; After (HTTP/2): listen A.B.C.D:443 ssl http2; </pre> <p>当然,如果你有相关的额外需求的话,也可以调节其他 <a href="/misc/goto?guid=4959654590273836456" rel="nofollow,noindex">Nginx HTTP/2 的配置选项</a> 。</p> <p>我们在 Canary 版本的机器上部署了 HTTP/2 大约一周的时间,而此时生产环境使用的仍然是 SPDY。在验证正确性以及相关性能评估之后,我们为 Web 服务全线开启了 HTTP/2。</p> <p><img src="https://simg.open-open.com/show/f3baae54904cbe994621d07f4b575216.png"></p> <p>从 SPDY 到 HTTP/2 平稳过渡(60 分钟的流量情况)</p> <p>该图展示了从 SPDY 至 HTTP/2 的过渡情况。 HTTP/1.1 连接并没有在该图展示出,我们分别在 23、26 以及 50 分钟的时候 ,逐渐在前端 Web 服务器上启用了 HTTP/2 支持。在此之前,流量则共同来自 Canary 机器上部署的 HTTP/2 以及生产环境中的 SPDY 。如图所示,最终我们则全线迁移到了 HTTP/2。</p> <h3>相关观察</h3> <p>我们在 canary 机器上详细监测了开启 HTTP/2 之后的性能情况,我们的观察点包括开启 HTTP/2 之后的性能效果,以及 HTTP/2 之后发现的问题,毕竟 HTTP/2 应用于生产还不太成熟。</p> <h3>性能提升</h3> <p>得益于更高效的的首部压缩算法(HPACK),我们注意到入口流量带宽的大幅度减少。</p> <p><img src="https://simg.open-open.com/show/3c04be35ff9cc06ff712dfe8836a7668.png"></p> <p>入口带宽流量情况(24 小时内流量)</p> <p>上图显示了 Canary 和生产机器每台机器上面的平均流量带宽情况,我们只在 Canary 机器上开启了 HTTP/2。每台 Canary 以及生产机器上都从负载均衡服务器上接收几乎是相同的流量。如图所示,在开启 HTTP/2 之后入口带宽明显减少(将近 50%)。值得注意的是,尽管我们之前在 Canary 和生产机器上使用 SPDY ,我们并没有开启 SPDY 首部压缩支持的原因是因为一个安全问题 <a href="/misc/goto?guid=4959673434430975798" rel="nofollow,noindex">(CVE-2012-4929)</a> 。至于出口流量,并没有显著变化,因为响应首部只占响应流量的一小部分。</p> <h3>一些注意事项</h3> <p>POST 请求延迟的增加。当我们在 Canary 机器上启用 HTTP/2 时,我们注意到中间延迟显著增加。下图展示了在 Canary 机器上开启 HTTP/2 后,相对于生产机器上增加了大约 50% 的请求延迟。经过调查我们发现激增的延迟来自 POST 请求。经过一番深入研究,我们发现这个问题是 Nginx 1.9.15 所固有的问题,相关讨论可以 <a href="/misc/goto?guid=4959673434520676513" rel="nofollow,noindex">参见 Nginx 的邮件列表</a> 。</p> <p><img src="https://simg.open-open.com/show/1f83cb63d1c263dc7653490252bb6703.png"></p> <p>激增的 50% 请求延迟(24 小时内流量)</p> <p>注意,增加的 50% 请求延迟(1.5 倍)取决于特定的流量负载。在大多数情况下,对于我们来说额外多了一个 RTT(Round Trip Time),并没有对我们的性能造成关键性影响。然而如果你的负载情况包括大量琐碎并且延迟敏感的 POST 请求,那么当你升级 Nginx 到 1.9.15 的话,激增的延迟就是一个重要的问题了。</p> <p>小心的启用 HTTP/2 ,尤其是在客户端不可控的情况下。目前 HTTP/2 依旧不太成熟,从我们的经验来看,一些客户端、第三方库以及相关的服务器实现,并没有完全的对 HTTP/2 实现兼容。比如:</p> <ul> <li>Chrome 没有处理好 RST_STREAM 携带 NO_ERROR 的问题,导致在 Nginx 1.9.14 下会出现这样的问题( <a href="/misc/goto?guid=4959673434604362765" rel="nofollow,noindex">Chromium Issue #603182</a> )。相关解决方法已经纳入 Nginx 1.9.15。</li> <li>当窗口空间(window space)耗尽的时候,Nghttp2 并不会发送 END_STREAM ,相关讨论请参见之前提到的 <a href="/misc/goto?guid=4959673434520676513" rel="nofollow,noindex">Nginx 的邮件列表</a></li> </ul> <p>由于我们的 API 用户可能使用的是不同的第三方 HTTP 库,在为我们的 API 启用 HTTP/2 之前,我们需要进行大量的测试。</p> <h3>相关调试工具</h3> <p>CloundFlare 发表过一篇文章,总结一些 <a href="/misc/goto?guid=4959673434701033580" rel="nofollow,noindex">好用的 HTTP/2 调试工具</a> ,除此之外,我们发现 Chrome net-internals 工具( chrome://net-internals/#http2 )也可以派上用场。下图则是访问 www.dropbox.com 是打开新的 HTTP/2 会话时的帧交换截图。</p> <p><img src="https://simg.open-open.com/show/183d22ef5aca66aa239cebd35f71189b.png"></p> <p>总而言之,我们已经平稳过渡到了 HTTP/2 ,下面是从这篇文章的几个相关总结。</p> <ul> <li>在 Nginx 中启用 HTTP/2 很简单。</li> <li>首部压缩会明显的减少入口带宽的流量。</li> <li>Nginx 1.9.15 上会出现 POST 请求延迟的增加。</li> <li>谨慎的启用 HTTP/2 ,因为还存在一些兼容性问题。</li> <li>Canary 验证以及 Nginx 的错误日志检查有助于及早发现潜在的问题。</li> </ul> <p>我们希望这篇文章能为那些热爱网络知识并有兴趣在服务中启用 HTTP/2 的人提供帮助,我们也希望听到大家的意见反馈。</p> <p> </p> <p>来自: <a href="/misc/goto?guid=4959673434784968249" rel="nofollow">http://code.leozhang2018.me/2016/05/13/Dropbox web 服务启用 HTTP2 的相关经验分享/</a></p> <p> </p>