網絡面經:HTTP 2.0的這些新特性,是時候了解一下了
面試中關于HTTP 2.0的面試題并不多,但基于HTTP 2.0的應用已經很多了,比如谷歌的gRPC框架就是基于HTTP 2.0來提升效率的。同時,HTTP 1.0中的存在的很多缺陷也都在HTTP 2.0中得到了解決。
所以,如果你在面試中脫穎而出,同時,在實踐中更好的理解類似gRPC這類框架的實現,了解HTTP 2.0還是非常必要的。而且HTTP 2.0也在很多場景下逐步替代HTTP 1.0。
HTTP 1.0存在的問題
了解過HTTP 1.0的協議實現之后,會發現它存在不少問題。
問題一:TCP連接數限制。為了避免網絡擁堵,占用過多的CPU和內存。因此,不同的瀏覽器會限制TCP連接的數量。
問題二:隊頭阻塞問題。隊頭阻塞(Head Of Line Blocking),每個TCP同時只能處理一個HTTP請求,瀏覽器遵循FIFO原則,如果上一個沒返回后續請求會被阻塞。
雖然提出了管道化(Pipelining)方案,但依舊存在諸多問題。比如,第一個響應慢還是會阻塞后續響應;服務器為了按序返回需要緩存多個響應,占用更多資源;瀏覽器中途斷連重試服務器可能得重新處理多個請求;還有必須客戶端 - 代理 - 服務器都支持管線化。
問題三:Header內容過多,每次都需重復發送,沒有相應的壓縮傳輸優化方案;
問題四:為了減少請求數,需做文件合并等優化工作,但同時會增加單個請求的延遲;
問題五:明文傳輸不安全;
HTTP 2.0的出現
針對HTTP 1.0的問題,RFC 7540定義了HTTP 2.0的協議規范和細節。HTTP 2.0的實現是基于SPDY協議的一些標準來實現的。
HTTP 2.0提供了:二進制分幀、首部壓縮、多路復用、請求優先級、服務器推送等優化。
HTTP 2.0是在SPDY(An experimental protocol for a faster web, The Chromium Projects)基礎上形成的下一代互聯網通信協議。HTTP/2 的目的是通過支持請求與響應的多路復用來較少延遲,通過壓縮HTTPS首部字段將協議開銷降低,同時增加請求優先級和服務器端推送的支持。
什么是SPDY協議
SPDY是Google開發的基于TCP協議的應用層協議。目標是優化HTTP協議的性能,通過壓縮、多路復用和優先級等技術,縮短網頁的加載時間并提高安全性。協議的核心思想是盡量減少TCP連接數。SPDY并不是一種用于替代HTTP的協議,而是對HTTP協議的增強。
互聯網工程任務組(IETF)對谷歌提出的SPDY協議進行了標準化,于2015年5推出了類似于SPDY協議的HTTP 2.0協議標準(簡稱HTTP/2)。谷歌因此宣布放棄對SPDY協議的支持,轉而支持HTTP/2。
下面詳細了解一下HTTP 2.0提供的新特性。
二進制分幀層 (Binary Framing Layer)
在保證HTTP1.x不受到影響的情況下,HTTP 2.0是怎樣突破HTTP 1.1的性能限制,改進傳輸性能,實現低延遲高吞吐量的呢?關鍵之一就是在應用層(HTTP)和傳輸層(TCP)之間增加一個二進制分幀層。二進制分幀層,是HTTP 2.0性能增強的核心。
HTTP 1.1在應用層以純文本的形式進行通信,而HTTP 2.0將所有的傳輸信息分割為更小的消息和幀,并對它們采用二進制格式編碼。同時,客戶端和服務端都需要引入新的二進制編碼和解碼的機制。如下圖所示,HTTP 2.0并沒有改變HTTP 1.x的語義,只是在應用層使用二進制分幀方式傳輸。
HTTP/2協議
關于二進制分幀,有三個相關概念:幀、消息和流。
幀:HTTP 2.0通信的最小單位,所有幀都共享一個8字節的首部,其中包含幀的長度、類型、標志、還有一個保留位,并且至少有標識出當前幀所屬的流的標識符,幀承載著特定類型的數據,如HTTP首部、負荷等等。
- +-----------------------------------------------+
- | Length (24) |
- +---------------+---------------+---------------+
- | Type (8) | Flags (8) |
- +-+-------------+---------------+-------------------------------+
- |R| Stream Identifier (31) |
- +=+=============================================================+
- | Frame Payload (0...) ...
- +---------------------------------------------------------------+
基于幀,以二進制傳輸代替原本的明文傳輸,原本的報文消息被劃分為更小的數據幀:
HTTP/2協議
在二進制分幀層上,HTTP 2.0會將所有傳輸的信息分為更小的消息和幀,并采用二進制格式編碼,其中HTTP 1.1的首部信息會被封裝到Headers幀,而Request Body則封裝到Data幀。
消息:比幀大的通訊單位,是指邏輯上的HTTP消息(請求/響應),一系列數據幀組成了一個完整的消息。比如一系列DATA幀和一個HEADERS幀組成了請求消息。由一個或多個幀組成。
流:比消息大的通訊單位,是TCP連接中的一個虛擬通道,可以承載雙向的消息。每個流都有一個唯一的整數標識符。
為防止兩端流ID沖突,客戶端發起的流具有奇數ID,服務器端發起的流具有偶數ID。所有HTTP 2. 0通信都在一個TCP連接上完成, 這個連接可以承載任意數量的雙向數據流Stream。相應地,每個數據流以消息的形式發送,而消息由一或多個幀組成,這些幀可以亂序發送,然后根據每個幀首部的流標識符重新組裝。
HTTP/2協議
二進制分幀層保留了HTTP的語義不受影響,包括首部、方法等,在應用層來看,和HTTP 1.x沒有差別。同時,所有同主機的通信能夠在一個TCP連接上完成。
- 單連接多資源的方式,減少服務端的鏈接壓力,內存占用更少,連接吞吐量更大;
- 由于TCP連接的減少而使網絡擁塞狀況得以改善,同時慢啟動時間的減少,使擁塞和丟包恢復速度更快。
多路復用 (MultiPlexing)
多路復用允許同時通過一個TCP連接發起多重的請求-響應消息。消息由幀構成,每幀數據上都標識屬于哪個流(StreamID),對方接收時根據流ID拼接每個流所有幀的數據,組成一塊完整的數據。這就是HTTP/2的多路復用。
流的概念實現了單連接上多請求-響應并行,解決了“隊頭阻塞(Head of line blocking)”的問題,減少了TCP連接數量和TCP連接慢啟動的問題。所以HTTP/2對于同一域名只需要創建一個連接,而不是像HTTP/1那樣需要創建6~8個連接。
需要注意的是不同流的數據可以交叉發送,但同一個流的數據只能順序發送。
服務端推送 (Server Push)
客戶端發送一個請求,服務器根據客戶端的請求,提前返回多個響應,這樣客戶端就不用發起后續請求。也就是說,在HTTP/2中,服務器可以對客戶端的一個請求發送多個響應。服務器向客戶端推送資源無需客戶端明確的請求。
如下圖,客戶端請求Stream 1(/page.html),服務端在返回Stream 1消息的同時推送了Stream 2(/script.js)和Stream 4(/style.css):
HTTP/2協議
如果一個請求是由主頁發送的,服務器可能會響應主頁內容、logo以及樣式表,因為它知道客戶端會用到這些。這樣不但減輕了數據傳送冗余步驟,也加快了頁面響應的速度,提高了用戶體驗。
服務端推送主要是針對資源內聯做出的優化,相較于HTTP/1.1資源內聯的優勢:
- 客戶端可以緩存推送的資源;
- 客戶端可以拒收推送過來的資源;
- 推送資源可以由不同頁面共享;
- 服務器可以按照優先級推送資源;
推送的缺點:所有推送的資源都必須遵守同源策略。換句話說,服務器不能隨便將第三方資源推送給客戶端,而必須是經過雙方的確認才行。
Header 壓縮 (HPACK)
HTTP/1.1并不支持HTTP首部壓縮,為此SPDY和HTTP/2應運而生, SPDY使用的是通用的算法,而HTTP/2則使用了專門為首部壓縮而設計的算法(HPACK算法)。
HTTP/2協議
HTTP協議是無狀態的,每次請求都必須附上所有信息(描述資源屬性),重傳數據達到幾百甚至幾千字節。所以,請求頭字段很多都是重復的,比如Cookie,一樣的內容每次請求都必須附帶,會浪費很多帶寬,也影響速度。
其實,對于相同的頭部,只需發送一次即可。HTTP/2對這一點做了優化,引入了頭信息壓縮機制。一方面,頭信息使用gzip或compress壓縮后再發送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,產生一個索引號,之后就不發送同樣字段了,只需發送索引號。
請求優先級
把HTTP消息分為很多獨立幀之后,就可以通過優化這些幀的交錯和傳輸順序進一步優化性能。HTTP/2中每個Stream都可以設置依賴 (Dependency) 和權重,可以按依賴樹分配優先級,解決了關鍵請求被阻塞的問題。
應用層的重置連接
對于HTTP/1來說,是通過設置tcp segment中的reset flag來通知對端關閉連接的。這種方式會直接斷開連接,下次再發請求就必須重新建立連接。HTTP/2引入 RST_STREAM類型的 frame,可以在不斷開連接的前提下取消某個request的stream,表現更好。
流量控制
TCP協議是通過sliding window算法來做流量控制的。發送方有一個sending window,接收方有一個receive window。HTTP/2的flow control類似receive window,數據接收方通知對方字節的flow window大小,表明還能接收的數據量。只有Data類型的frame才有flow control功能。
通過上述方式,可以限制另一端發送數據。對于每個流來說,兩端都必須告訴對方自己還有足夠的空間來處理新的數據,而在該窗口被擴大前,另一端只被允許發送這么多數據。
小結
每一個新的協議的應用普及都需要一個過程,HTTP/2也不例外。還好的是,它是上層協議,而且只是在HTTP/1和TCP之間添加了一層,逐步被使用必然是趨勢。在了解了HTTP/2的這些新特性之后,或許你已經明白,為什么越來越多的瀏覽器、中間件開始采用HTTP/2了。因為,它的確非常高效,值得你學習并運用。