Dropbox web 服務啟用 HTTP/2 的相關經驗分享(譯)
在 Dropbox ,我們的運維團隊于近日升級了前端 Nginx 服務器開啟了 web 服務的 HTTP/2 支持。在本篇文章中,我們將就此次 HTTP/2 的升級過渡,分享我們的一些經驗以及相關發現。總體來說此次升級還算平滑,然而依舊踩了很多的“坑”碰到了不少注意事項,希望會對他人有所幫助。
背景:HTTP/2 以及 Dropbox web 服務架構
HTTP/2( RFC 7540 )是新一代的 HTTP 協議版本,它基于 SPDY ,相比于 HTTP/1.1 提供了數項性能優化。這些優化包括:更高效的首部壓縮(Header compression)、服務端推送(Server push)、同一連接上的流復用(Stream multiplexing),等等。如今, HTTP/2 已經被大部分瀏覽器所支持 。
Dropbox 使用開源的 Nginx 處理 SSL 連接并且對 web 流量進行七層的負載均衡。在升級之前我們前端的 Web 服務器運行的是 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 ,也就是最新的 stable 版本。
Nginx 的升級包括基本的配置文件修改,啟用 HTTP/2 的支持,需要將 http2 指令添加到 listen 字段。就我們而言,因為之前已經開啟 SPDY,所以只需將 spdy 替換成 http2 就行了。
Before (SPDY): listen A.B.C.D:443 ssl spdy; After (HTTP/2): listen A.B.C.D:443 ssl http2;
當然,如果你有相關的額外需求的話,也可以調節其他 Nginx HTTP/2 的配置選項 。
我們在 Canary 版本的機器上部署了 HTTP/2 大約一周的時間,而此時生產環境使用的仍然是 SPDY。在驗證正確性以及相關性能評估之后,我們為 Web 服務全線開啟了 HTTP/2。
從 SPDY 到 HTTP/2 平穩過渡(60 分鐘的流量情況)
該圖展示了從 SPDY 至 HTTP/2 的過渡情況。 HTTP/1.1 連接并沒有在該圖展示出,我們分別在 23、26 以及 50 分鐘的時候 ,逐漸在前端 Web 服務器上啟用了 HTTP/2 支持。在此之前,流量則共同來自 Canary 機器上部署的 HTTP/2 以及生產環境中的 SPDY 。如圖所示,最終我們則全線遷移到了 HTTP/2。
相關觀察
我們在 canary 機器上詳細監測了開啟 HTTP/2 之后的性能情況,我們的觀察點包括開啟 HTTP/2 之后的性能效果,以及 HTTP/2 之后發現的問題,畢竟 HTTP/2 應用于生產還不太成熟。
性能提升
得益于更高效的的首部壓縮算法(HPACK),我們注意到入口流量帶寬的大幅度減少。
入口帶寬流量情況(24 小時內流量)
上圖顯示了 Canary 和生產機器每臺機器上面的平均流量帶寬情況,我們只在 Canary 機器上開啟了 HTTP/2。每臺 Canary 以及生產機器上都從負載均衡服務器上接收幾乎是相同的流量。如圖所示,在開啟 HTTP/2 之后入口帶寬明顯減少(將近 50%)。值得注意的是,盡管我們之前在 Canary 和生產機器上使用 SPDY ,我們并沒有開啟 SPDY 首部壓縮支持的原因是因為一個安全問題 (CVE-2012-4929) 。至于出口流量,并沒有顯著變化,因為響應首部只占響應流量的一小部分。
一些注意事項
POST 請求延遲的增加。當我們在 Canary 機器上啟用 HTTP/2 時,我們注意到中間延遲顯著增加。下圖展示了在 Canary 機器上開啟 HTTP/2 后,相對于生產機器上增加了大約 50% 的請求延遲。經過調查我們發現激增的延遲來自 POST 請求。經過一番深入研究,我們發現這個問題是 Nginx 1.9.15 所固有的問題,相關討論可以 參見 Nginx 的郵件列表 。
激增的 50% 請求延遲(24 小時內流量)
注意,增加的 50% 請求延遲(1.5 倍)取決于特定的流量負載。在大多數情況下,對于我們來說額外多了一個 RTT(Round Trip Time),并沒有對我們的性能造成關鍵性影響。然而如果你的負載情況包括大量瑣碎并且延遲敏感的 POST 請求,那么當你升級 Nginx 到 1.9.15 的話,激增的延遲就是一個重要的問題了。
小心的啟用 HTTP/2 ,尤其是在客戶端不可控的情況下。目前 HTTP/2 依舊不太成熟,從我們的經驗來看,一些客戶端、第三方庫以及相關的服務器實現,并沒有完全的對 HTTP/2 實現兼容。比如:
- Chrome 沒有處理好 RST_STREAM 攜帶 NO_ERROR 的問題,導致在 Nginx 1.9.14 下會出現這樣的問題( Chromium Issue #603182 )。相關解決方法已經納入 Nginx 1.9.15。
- 當窗口空間(window space)耗盡的時候,Nghttp2 并不會發送 END_STREAM ,相關討論請參見之前提到的 Nginx 的郵件列表
由于我們的 API 用戶可能使用的是不同的第三方 HTTP 庫,在為我們的 API 啟用 HTTP/2 之前,我們需要進行大量的測試。
相關調試工具
CloundFlare 發表過一篇文章,總結一些 好用的 HTTP/2 調試工具 ,除此之外,我們發現 Chrome net-internals 工具( chrome://net-internals/#http2 )也可以派上用場。下圖則是訪問 www.dropbox.com 是打開新的 HTTP/2 會話時的幀交換截圖。
總而言之,我們已經平穩過渡到了 HTTP/2 ,下面是從這篇文章的幾個相關總結。
- 在 Nginx 中啟用 HTTP/2 很簡單。
- 首部壓縮會明顯的減少入口帶寬的流量。
- Nginx 1.9.15 上會出現 POST 請求延遲的增加。
- 謹慎的啟用 HTTP/2 ,因為還存在一些兼容性問題。
- Canary 驗證以及 Nginx 的錯誤日志檢查有助于及早發現潛在的問題。
我們希望這篇文章能為那些熱愛網絡知識并有興趣在服務中啟用 HTTP/2 的人提供幫助,我們也希望聽到大家的意見反饋。
來自: http://code.leozhang2018.me/2016/05/13/Dropbox web 服務啟用 HTTP2 的相關經驗分享/