使用HTTP/2提升效能的7個建議
歷史悠久的超文字傳輸協議,即HTTP標準,最近版本升級了。HTTP/2在2015年5月被批准,目前已經在很多Web瀏覽器和伺服器中得到實現(包括NGINX Plus和開源NGINX)。大約有三分之二的瀏覽器已經支援HTTP/2,而且這個比例每月都在增加。
HTTP/2構建在Google SPDY協議基礎之上,Chrome將在2016年年初停止對後者的支援。NGINX是最早支援SPDY的,如今同樣率先支援了HTTP/2。為此,我們還發布了詳盡的白皮書(PDF),介紹了HTTP/2以及它如何基於SPDY構建,並展示瞭如何實現這個新協議。
HTTP/2的重要特性完全源自SPDY。
- HTTP/2是二進位制(而文字)協議,因此更簡潔高效;
- 它針對每個域只使用一個多路複用的連線,而不是每個檔案一個連線;
- 首部使用特製的HPACK協議(而非SPDY中使用的gzip)壓縮;
- HTTP/2設計了複雜的優先順序排定規則,幫助瀏覽器首先請求最急需的檔案,而NGINX已經支援(SPDY的方案要簡單一些)。
現在,你需要決定是否遷移到HTTP/2,而其中關鍵是知道如何最大限度地利用它。這篇文章會帶你瞭解從效能角度考慮為什麼要做這個決定,以及如何實現。接下來我們要逐一討論關於HTTP/2效能的7個小建議。
- 現在是否需要遷移到HTTP/2
- 終止HTTP/2和TLS
- 考慮從SPDY開始
- 找出為HTTP/1.x優化的程式碼
- 部署HTTP/2或SPDY
- 再談HTTP/1.x優化
- 實現智慧分域
注意:嚴格來講,SPDY和HTTP/2都不需要TLS,但它們在使用SSL/TLS的時候用處最大,而且瀏覽器只在使用SSL/TLS時才支援SPDY或HTTP/2。
建議一:現在是否需要遷移到HTTP/2
實現HTTP/2很簡單,看看我們的白皮書就明白了(PDF)。不過,HTTP/2並不是萬能的銀彈,它只對某些Web應用有用,對另外一些則沒那麼有用。
如果你使用SSL/TLS(以後簡稱TLS),那麼HTTP/2可以提升網站效能。如果你沒有,那在使用HTTP/2之前要先支援TLS。這時候,使用TLS的效能損耗大致可以被使用HTTP/2的效能提升抵銷。不過還是建議你在實際應用之前先測試一下。
HTTP/2有五大優勢。
- 每個伺服器只用一個連線。HTTP/2對每個伺服器只使用一個連線,而不是每個檔案一個連線。這樣,就省掉了多次建立連線的時間,這個時間對TLS尤其明顯,因為TLS連線費時間。
- 加速TLS交付。HTTP/2只需一次耗時的TLS握手,並且通過一個連線上的多路利用實現最佳效能。HTTP/2還會壓縮首部資料,省掉HTTP/1.x時代所需的一些優化工作,比如拼接檔案,從而提高快取利用率。
- 簡化Web應用。使用HTTP/2可以讓Web開發者省很多事,因為不用再做那些針對HTTP/1.x的優化工作了。
- 適合內容混雜的頁面。HTTP/2特別適合混合了HTML、CSS、JavaScript、圖片和有限多媒體的傳統頁面。瀏覽器可以優先安排那些重要的檔案請求,讓頁面的關鍵部分先出現,快出現。
- 更安全。通過減少TLS的效能損失,可以讓更多應用使用TLS,從而讓使用者資訊更安全。
HTTP/2的多路複用示意圖
相應地,HTTP/2也有五個不足之處。
- 單連線開銷比較大。HPACK資料壓縮演算法會更新兩端的查詢表。這樣可以讓連線有狀態,而破壞狀態就意味著要重建查詢表,另外單連線佔用記憶體較多。
- 你可能不需要SSL。如果你的資料不需要保護,或者已經使用DRM或其他編碼進行保護了,那麼TLS的安全性對你可能無所謂。
- 需要拋棄針對HTTP/1.x的優化。HTTP/1.x優化在支援HTTP/2的瀏覽器中會影響效能,因此可能需要花時間把它們推倒重來。
- 對下載大檔案不利。如果你的應用主要提供大檔案下載或者流媒體播放,那可能不想用TLS,而且在只有一個流的情況下,多路複用也體現不出什麼優勢。
- 你的客戶也許不在乎。你的客戶很可能不在乎他分享的自家貓咪的視訊是否受到TLS和HTTP/2的保護。
總之,一切要看效能。這方面,有好訊息也有壞訊息。
好訊息是我們在內部對NGINX做過測試,結果從理論上能夠得到印證:對於要通過典型網路延遲請求的混合內容網頁,HTTP/2的效能好於HTTP/1.x和HTTPS。基於連線的RTT,結果可以分三種情況。
- 很低的RTT(0-20ms):HTTP/1.x、HTTP/2和HTTPS基本無差別。
- 典型網路RTT(30-250ms):HTTP/2比HTTP/1.x快,而且它們都比HTTPS快。美國兩個相鄰城市間的RTT約為30 ms,而東西海岸間(約3000英里)則約為70 ms。東京到倫敦間最短路徑的RTT大約240 ms。
- 高RTT(300ms及以上):HTTP/1.x比HTTP/2快,後者又比HTTPS快。
這張圖顯示了首次渲染的時間,也就是使用者第一次在自己螢幕上看到網頁內容的時間。這個時間一般認為關係到使用者對網站響應速度的感知。
要想了解我們測試的更多內容,請看這個HTTP/2的介紹視訊,來源是nginx.conf 2015。
然而,每個網頁都不相同,實際上每個使用者的會話也不一樣。如果你託管流媒體或提供大檔案下載,那你的決定可能不一樣,甚至相反。
你最終可能發現投入產出比並不明顯。如果是這樣,那你得多學習一下,針對自己的內容多做一些測試,然後我們們可以聊一聊。(想找點資料?可以看看NGINX網路研討:What’s New in HTTP/2?)。
建議二:終止HTTP/2和TLS
終止協議意味著客戶端使用期望的協議連線代理伺服器,比如TLS或HTTP/2,然後代理伺服器再去連線應用伺服器、資料庫伺服器等,但不需要使用相同的協議,如下圖所示。
使用獨立的伺服器終止協議意味著使用多伺服器架構。多伺服器可能是多個物理伺服器、多個虛擬伺服器,或者AWS這樣的雲環境中的多個虛擬伺服器例項。多伺服器就比單伺服器複雜,或者比應用伺服器/資料庫伺服器的組合複雜。不過,多伺服器架構有很多好處,而且很多流量大的網站也必須用這種架構。
配置了伺服器或者虛擬伺服器之後,很多事情都成為可能。新伺服器可以分擔其他伺服器的負載,可用於負載平衡、靜態檔案快取和其他用途。另外,也可以讓新增和替換應用伺服器或其他伺服器更容易。
NGINX和NGINX Plus經常被用來終止TLS和HTTP/2協議、負載平衡。已有環境不必改動,除非要把NGINX伺服器挪到前端。
建議三:考慮從SPDY開始
SPDY是HTTP/2的上一代,總體效能相同。因為它已經出現好幾年了,所以有很多瀏覽器支援SPDY卻不支援HTTP/2。不過,在本文寫作時,這個支援上的差距正在縮小。具體來說,有三分之二的瀏覽器支援HTTP/2,而有五分之四的瀏覽器支援SPDY。
如果你著急採用新的Web傳輸協議,又想盡可能覆蓋更多使用者,可以先從SPDY開始。然後到2016年初,即谷歌不再支援SPDY的時候,再切換到HTTP/2,很簡單,至少在NGINX中如此。那時候,更多使用者會擁有支援HTTP/2的瀏覽器,而你已經為其中大部分使用者提供了很好的效能。
建議四:找出為HTTP/1.x優化的程式碼
在決定採用HTTP/2之前,首先得知道你的程式碼有哪些是針對HTTP/1.x優化過的。大概有四方面的優化。
- 分域儲存。為了實現並行請求檔案,你可能把檔案分散到了不同的域裡,CDN會自動這麼做。但分域儲存會影響HTTP/2的效能,建議使用HTTP/2友好的分域儲存(建議七),只針對HTTP/1.x使用者分域。
- 雪碧圖。雪碧圖把很多圖片拼成一個檔案,然後通過程式碼按需取得每個圖片。雪碧圖在HTTP/2的環境下沒太大用處,但還是有點用的。
- 拼接的程式碼檔案。與使用雪碧圖的原因類似,很多獨立的檔案也會被弄成一個,然後瀏覽器再從其中找到並執行需要的檔案。
- 插入行內的檔案。CSS程式碼、JavaScript程式碼,甚至圖片等被直接插到HTML檔案中的內容。這樣可以減少檔案傳輸,代價是初始HTML檔案較大。
後面三種優化都涉及把小檔案塞進一個較大的檔案裡,目的是減少新建連線的初始化和握手,這些操作對TLS而言非常費時間。
第一種優化即分域儲存恰恰相反,強制開啟多個連線,目的是並行地從不同的域獲取檔案。這兩種看似矛盾的技術對於HTTP/1.x下的站點卻十分有效。然而,要用好這兩種技術,必須投入大量時間、精力和資源,用於實現、管理和運維。
在採用HTTP/2之前,需要找出應用了這些優化的程式碼,分析一下它們會不會影響你的應用設計和工作流程。這樣在遷移到HTTP/2之後,就可以著手改造它們,甚至撤銷某些優化。
建議五:部署HTTP/2或SPDY
事實上,部署HTTP/2或SPDY並不難。如果你使用NGINX,只要在配置檔案中啟動相應的協議就可以了,參見這裡瞭解如何啟用HTTP/2(PDF)。瀏覽器和伺服器會協商採用什麼協議,如果瀏覽器支援HTTP/2(而且也在使用TLS),就會使用HTTP/2。
配置完伺服器後,使用支援HTTP/2瀏覽器的使用者就會基於HTTP/2執行你的應用,而使用舊版本瀏覽器的使用者則會繼續使用HTTP/1.x執行你的應用,如下圖所示。如果你的網站流量非常大,那麼應該監測改變前後的效能,對於效能降低的情況,可能就得撤銷更改。
注意:使用HTTP/2及其單連線之後,NGINX某些配置的重要性會很明顯,特別要注意的是output_buffers、proxy_buffers和ssl_buffer_size等指令,多測試一下。參見general configuration notes,特定的SSL建議(在這裡 and here),以及NGINX關於SSL效能的白皮書(PDF)。
注意:使用HTTP/2傳輸密文要格外注意。HTTP/2的RFC中有一個長長的列表,列出了要避免的加密套件。建議你自己也搞一個表格,啟用ssl_buffer_size,然後在所有常用的瀏覽器版本下測試你想用的加密套件。
建議六:再談HTTP/1.x優化
你說奇怪不,撤銷和修改針對HTTP/1.x優化的程式碼居然是實現HTTP/2最有創意的部分。這裡面有幾個問題要注意,因為很多事怎麼做都是可以的。
在開始運作之前,必須考慮舊版本瀏覽器使用者是否好過。之後,可以採取三個策略撤銷和修改HTTP/1.x的優化。
- 什麼也不用做。假如你並沒有針對HTTP/1.x做過優化,或者只做過少量優化,那麼你幾乎什麼也不用做,就可以直接遷移到HTTP/2。
- 有選擇地去做。第二種情況是減少合併某些檔案,而不是完全不合並。比如,牽扯到很多場景的雪碧圖就不用動,而被塞得滿滿的HTML可能就要分離出來一些。
- 完全撤銷HTTP/1.x優化(不過請先參考建議七中關於分域儲存的建議)。可以不再做以前做過的任何優化。
快取還是普適的。理論上,快取操作非常適合小檔案特別多的情況。但是,小檔案多也意味著檔案I/O多。因此一些相近檔案的合併還是必要的,一方面要考慮工作流程,另一方面要考慮應用效能。建議多關注一下其他人在過渡到HTTP/2過程中的一些經驗。
建議七:實現智慧分域
分域儲存可能是最極端但也最成功的HTTP/1.x優化策略。它能夠提升HTTP/1.x下的應用效能,但在HTTP/2之下,其效能提升可以忽略不講(因為只有一個連線。)
對HTTP/2友好的分域,要保證以下兩點。
- 讓多個域名解析到同一個IP。
- 確保證照包含萬用字元,以便所有分域名都可以使用,適當的多域證照當然也可以。
具體細節,請參考這裡。
有了這些保障,分域還會繼續對HTTP/1.x有效,即域名仍然可以觸發瀏覽器建立更多連線,但對HTTP/2則無效,因為這些域名會被看成同一個域,一個連線就可以訪問所有域名了。
小結
HTTP/2和TLS組合可以提升你的站點效能,並且讓使用者覺得你的網站很安全。無論你是率先在自己的應用裡實現HTTP/2,還是要趕超競爭對手,都可以又快又好地實現對HTTP/2的支援。
希望這篇文章能讓你以最少的努力獲得最大的HTTP/2效能收益,而且從此你可以把注意力集中到編寫更快、更有效、更安全的應用上,讓自己的應用更容易維護和運維。
參考資源
- 要全面瞭解HTTP/2,可以看看NGINX的白皮書(PDF)。
- 在Can I use網站中可以查到瀏覽器對各種前端技術的支援情況,包括SPDY和HTTP/2。
- 要了解我們測試的細節,參考這裡HTTP/2 presentation。
- NGINX有一個Web研討班:What’s New in HTTP/2?,討論了核心特性並給出了實現建議。
- 要了解NGINX關於效能的建議,請參考我們的部落格:10 Tips for 10x Application Performance。
原文:https://www.nginx.com/blog/7-tips-for-faster-http2-performance/
相關文章
- Java中提升效能對程式碼作的建議(轉Mark)Java
- 再談HTTP2效能提升之背後原理—HTTP2歷史解剖HTTP
- 日常開發中,提升技術的13個建議
- HTTP協議(2)HTTP協議
- 幫你提升Python執行效能的7 個習慣Python
- 邦芒攻略:提升職場核心競爭力的7點建議
- DBA 的 7 點建議
- HTTP協議之:HTTP/1.1和HTTP/2HTTP協議
- HTTP2 協議HTTP協議
- 提升 JumpServer 安全的10條建議 | IDCFServer
- 滲透測試常用的7個工具,建議新手收藏!
- 瞭解HTTP/2協議HTTP協議
- 7 個建議讓 Code Review 高效又高質View
- HTTP協議圖文簡述--HTTP/HTTPS/HTTP2HTTP協議
- [HTTP 系列] 第 2 篇 —— HTTP 協議那些事HTTP協議
- UITableView效能優化的幾點建議UIView優化
- 從效能角度幫你理解HTTP協議HTTP協議
- 6個提升PostgreSQL效能的小技巧SQL
- 5個介面效能提升的通用技巧
- 真正“搞”懂HTTP協議13之HTTP2HTTP協議
- 使用 preloadRouteComponents 提升 Nuxt 應用的效能UX
- 一個有趣的實驗:用0.1f 替換 0,效能提升 7 倍!
- HTTP協議幾個版本的比較HTTP協議
- Perforce 使用建議
- 網路安全最常使用的25個Linux命令,建議收藏!Linux
- 記一次介面效能優化實踐總結:優化介面效能的八個建議優化
- 小胖親測,分享3個實用建議,幫助你提升工作效率
- [需求建議]外掛建議:建議出一個時間軸外掛
- http協議中比較重要的幾個頭HTTP協議
- dotnet 使用 Crossgen2 對 DLL 進行 ReadyToRun 提升啟動效能ROS
- HTTP2 協議長文詳解HTTP協議
- 深入理解 Web 協議 (三):HTTP 2Web協議HTTP
- 使用Netty構建一個帶註解的Http伺服器框架NettyHTTP伺服器框架
- 02 前端HTTP協議(圖解HTTP) 之 簡單的HTTP協議前端HTTP協議圖解
- 改善 Python 程式的 91 個建議Python
- 給2019前端的5個建議前端
- 構建API的7個技巧API
- [譯] 使用 PhpFastCache 提升網站效能PHPAST網站
- 里程碑式 Dubbo 2.7.5 版本釋出,效能提升30%,支援 HTTP/2、TLS、Protobuf等特性HTTPTLS