IP協議棧之HTTP2.0

1 前言

今天一起來研究Http協議的一些事情,通過本文你將瞭解到以下內容:

  • Http協議各版本的對比和優缺點
  • Http2.0協議相關的SPDY協議、二進制分幀協議、多路複用、首部壓縮、服務推送等基本原理

乘風破浪前往知識的海洋吧, 大白船長 要開船了!

理解TCP/IP協議棧之HTTP2.0

2. Http協議各版本的對比

Http超文本傳輸協議同空氣一般, 感觸不到它的存在但是又無處不在 ,筆者從維基百科摘錄了一些Http協議的發展歷程的簡單信息,一起來看下吧:

超文本傳輸協議是 分佈式協作超媒體信息系統的應用協議 。超文本傳輸協議是萬維網數據通信的基礎,在萬維網中超文本文檔包括到用戶可以輕鬆訪問的其他資源的超鏈接。

蒂姆·伯納斯·李於1989年在歐洲核子研究中心發起了超文本傳輸協議的開發。早期的超文本傳輸協議徵求意見(RFCs)的開發是由互聯網工程任務組(IETF)和萬維網聯盟(W3C)共同努力的結果,其工作後來轉移到IETF。

萬維網之父蒂姆·伯納斯·李簡介

Tim Berners-Lee是英國工程師和計算機科學家,最著名的是萬維網的發明者。他是 牛津大學計算機科學教授和麻省理工學院教授

他於1989年3月12日提出了一種信息管理系統,然後在同年11月中旬通過Internet實現了超文本傳輸協議HTTP客戶端和服務器之間的

首次成功通信

他是萬維網聯盟W3C的負責人,該聯盟負責監督Web的持續發展,他還是 萬維網基金會的創始人 ,還是麻省理工學院計算機科學和人工智能實驗室CSAIL的3Com創始人主席和高級研究員,他也是網絡科學研究計劃WSRI的主任和MIT集體智慧中心的顧問委員會成員,他也是開放數據研究所的 創始人兼總裁 ,目前是社交網絡MeWe的顧問。

2004年,伯納斯·李因其開創性工作而被女王伊麗莎白二世 封為爵士 。在2009年4月,他當選為 美國國家科學院外籍研究員 ,位列《時代》雜誌的 20世紀100位最重要人物 名單被譽為“萬維網發明者”獲得了2016年 圖靈獎

理解TCP/IP協議棧之HTTP2.0

http各個版本的基本情況

http協議經過20多年的演進出現過 0.9、1.0、1.1、2.0、3.0 五個主要版本,筆者畫了張圖看下:

理解TCP/IP協議棧之HTTP2.0

A.Http0.9版本

0.9是鼻祖版本,它的主要特點包括:

  • 請求方法支持有限只支持GET請求方式,不支持其他請求方式 因此客戶端向服務端傳輸信息的量非常有限,也就是現在常用的Post請求無法使用
  • 不支持請求頭header不能在請求中指定版本號,服務端只具有返回HTML字符串的能力
  • 響應即關閉服務端相響應之後,立即關閉TCP連接

B.Http1.0版本

1.0版本主要是對0.9版本的強化,效果也比較明顯,主要特性和缺點包括:

  • 豐富請求方法請求方式新增了POST,DELETE,PUT,HEADER等方式,提高了客戶端向服務端發送信息的量級
  • 增加請求頭和響應頭增添了請求頭和響應頭的概念,可以在通信中指定了HTTP協議版本號,以及其他header信息,使得C/S交互更加靈活方便
  • 豐富數據傳輸內容擴充了傳輸內容格式包括: 圖片、音視頻資源、二進制 等都可以進行傳輸,相比0.9的只能傳輸html內容讓http的應用場景更多
  • 鏈接複用性差1.0版本中每個TCP連接只能發送一個請求,數據發送完畢連接就關閉,如果還要請求其他資源,就必須重新建立連接。TCP為了保證正確性和可靠性需要客戶端和服務器三次握手和四次揮手,因此建立連接成本很高,基於擁塞控制開始時發送速率較慢,所以1.0版本的
    性能並不理想
  • 無狀態無連接的弊端1.0版本是 無狀態且無連接 的,換句話說就是服務器不跟蹤不記錄請求過的狀態,客戶端每次請求都需要建立tcp連接不能複用,並且1.0規定在前一個請求響應到達之後下一個請求才能發送,如果前一個阻塞後面的請求就會被阻塞。 丟包和亂序問題 和高成本的鏈接過程讓複用和 隊頭阻塞 產生很多問題,所以 無連接無狀態 是1.0版本的一個 弱肋

C.Http1.1版本

1.1版本在1.0版本發佈後大約1年就推出了,是 對1.0版本的優化和完善 ,1.1版本的主要特點包括:

  • 增加長連接新增Connection字段,可以設置keep-alive值保持連接不斷開,即 TCP 連接默認不關閉,可以被多個請求複用,這也是1.1版本很重要的優化,但是在S端服務器只有處理完一個回應,才會進行下一個回應。要是前面的回應特別慢,後面就會有許多請求排隊等著,仍然存在隊頭阻塞問題。
  • 管道化在長連接的基礎上,管道化可以不等第一個請求響應繼續發送後面的請求,但響應的順序還是按照請求的順序返回,即在同一個TCP連接中,客戶端可以同時發送多個請求,進一步改進了HTTP協議的傳輸效率。
  • 更多的請求方法增加了 PUT、PATCH、OPTIONS、DELETE 等請求方式。
  • host字段Host字段用來指定服務器的域名,這樣就可以將多種請求發往同一臺服務器上的不同網站,提高了機器的複用,這個也是重要的優化

D.Http2.0版本

2.0版本是個里程碑式的版本,相比1.x版本有了非常多的優化去適應當前的網絡場景,其中幾個重要功能點包括:

  • 二進制格式1.x是文本協議,然而2.0是以二進制幀為基本單位,可以說是一個二進制協議,將所有傳輸的信息分割為消息和幀,並採用二進制格式的編碼,一幀中包含數據和標識符,使得網絡傳輸變得高效而靈活。
  • 多路複用這是一個非常重要的改進,1.x中建立多個連接的消耗以及效率都存在問題,2.0版本的多路複用多個請求共用一個連接,多個請求可以同時在一個TCP連接上併發,主要藉助於二進制幀中的標識進行區分實現鏈路的複用。
  • 頭部壓縮2.0版本使用使用HPACK算法對頭部header數據進行壓縮,從而減少請求的大小提高效率,這個非常好理解,之前每次發送都要帶相同的header,顯得很冗餘,2.0版本對頭部信息進行增量更新有效減少了頭部數據的傳輸。
  • 服務端推送這個功能有點意思,之前1.x版本服務端都是收到請求後被動執行,在2.0版本允許服務器主動向客戶端發送資源,這樣在客戶端可以起到加速的作用。

3 Http2.0 詳解

前面對比了幾個版本的演進和優化過程,接下來深入研究下2.0版本的一些特性及其基本實現原理。

從對比來看2.0版本並不是在1.1版本上的一些 優化而是革新 ,因為2.0揹負了更多的 性能目標任務 ,1.1雖然增加了長連接和管道化,但是從根本上並沒有實現真正的高性能。

2.0的設計目標是在 兼容1.x語義和操作 的基礎上,給用戶帶來 更快捷、更簡單、更安全

的體驗高效地利用當前的網絡帶寬,為此2.0做了很多調整主要包括: 二進制化分幀、多路複用、頭部壓縮 等。

akamai做了http2.0和http1.1在加載過程中的對比效果( 實驗中加載379個小片段 在筆者的電腦上的加載時間是0.99s VS 5.80s ):

理解TCP/IP協議棧之HTTP2.0

<code>https://http2.akamai.com/demo/<code>

3.1 SPDY協議

要說2.0版本標準和新特性就必須提谷歌的

SPDY協議 ,看一下百度百科:

SPDY是Google開發的基於TCP的會話層協議,用以最小化網絡延遲,提升網絡速度,優化用戶的網絡使用體驗。SPDY並不是一種用於替代HTTP的協議,而是對HTTP協議的增強。

新協議的功能包括 數據流的多路複用、請求優先級以及HTTP報頭壓縮 。谷歌表示引入SPDY協議後,在實驗室測試中頁面加載速度比原先快64%。

隨後SPDY協議得到 Chrome、Firefox 等大型瀏覽器的支持,在一些大型網站和小型網站種部署,這個高效的協議引起了 HTTP工作組 的注意,在 此基礎上制定了官方Http2.0標準

之後幾年SPDY和Http2.0繼續演進相互促進,Http2.0讓服務器、瀏覽器和網站開發者在新協議中獲得更好的體驗,很快被大眾所認可。

3.2 二進制分幀層

二進制分幀層 binary framing layer 在不修改請求方法和語義的基礎上,重新設計了

編碼機制 ,如圖為http2.0分層結構( 圖片來自參考4 ):

理解TCP/IP協議棧之HTTP2.0

二進制編碼機制使得通信可以在 單個TCP連接 上進行,該連接在整個對話期間一直處於活躍狀態。

二進制協議將通信 數據分解為更小的幀 ,數據幀充斥在C/S之間的雙向數據流中,就像雙向多車道的高速路,來往如織川流不息:

理解TCP/IP協議棧之HTTP2.0

要理解二進制分幀層需要知道四個概念:

  • 鏈接Link就是指一條C/S之間的TCP鏈接,這是個基礎的鏈路數據的高速公路
  • 數據流Stream已建立的TCP連接內的雙向字節流,TCP鏈接中可以承載一條或多條消息
  • 消息Message消息屬於一個數據流,消息就是邏輯請求或響應消息對應的完整的一系列幀,也就是幀組成了消息
  • 幀Frame幀是通信的最小單位,每個幀都包含幀頭和消息體,標識出當前幀所屬的數據流

四者是 一對多的 包含 關係,筆者畫了一張圖:

理解TCP/IP協議棧之HTTP2.0

再來看一下HeadersFrame頭部幀的結構:

理解TCP/IP協議棧之HTTP2.0

再來看一下HeadersFrame頭部幀的結構:從各個域可以看到長度、類型、標誌位、 流標識符、 數據淨荷等,感興趣可以閱讀rfc7540相關文檔。

<code>https://httpwg.org/specs/rfc7540.html/<code>

總之 2.0版本將通信數據分解為二進制編碼幀進行交換,每個幀對應著特定數據流中的特定消息,所有幀和流都在一個TCP連接內複用,二進制分幀協議是2.0其他功能和性能優化的重要基礎。

理解TCP/IP協議棧之HTTP2.0

3.3 多路複用

1.1版本中存在 隊首阻塞問題 ,因此如果客戶端要發起多個並行請求來提升性能,必須使用 多個TCP連接 ,這樣就要承受 更大延時和建鏈拆鏈成本 ,不能有效利用TCP鏈接。

由於2.0版本中使用新的二進制分幀協議突破了1.0的諸多限制,從根本上實現了真正的 請求和響應多路複用

客戶端和服務器將交互數據分解為 相互獨立的幀 ,互不影響地 交錯傳輸 ,最後再在對端根據 幀頭中的流標識符 把它們 重新組裝 起來,從而實現了TCP鏈接的多路複用。

如圖展示了2.0版本的基於幀的消息通信過程 ( 圖片來自參考4 ) :

理解TCP/IP協議棧之HTTP2.0

理解TCP/IP協議棧之HTTP2.0

3.4 首部壓縮

A.Header冗餘傳輸

我們都知道http請求都有header部分,每個包都有並且相對於一條鏈接而言 大部分的包的header部分都是相同 的,這樣的話每次傳輸相同的部分確實 非常浪費

現代網絡中每個網頁平均包含100多個http請求,每個請求頭平均有300-500字節,總數據量達到幾十KB以上,這樣可能造成數據延時,尤其複雜 的WiFi環境或者蜂窩網絡 ,這樣只能看到手機在轉圈,但是這些請求頭之間通常幾乎沒有變化,在本已經擁擠的鏈路中多次傳輸相同的數據部分確實不是高效做法。

基於TCP設計的 擁塞控制 具有 線增積減AIMD特性 ,如果發生丟包那麼傳輸速率將大幅度下降,這樣在擁擠的網絡環境中大的包頭意味著只能 加劇擁塞控制造成的低速率傳輸

B.Http壓縮和犯罪攻擊

在2.0版本的HPACK算法之前,http壓縮使用gzip去壓縮,後來提出的SPDY算法對Headers進行特殊設計,但是它依舊使用的是 DEFLATE算法

在後面的一些實際應用中發現 DEFLATE和SPDY都有被攻擊的危險 ,因為DEFLATE算法使用後向 字符串匹配和動態Huffman編碼 ,攻擊者可以控制部分請求頭部通過修改請求部分然後看壓縮之後大小改變多少,如果變小了攻擊者就知道注入的文本和請求中的某些內容有重複。

這個過程有點像 俄羅斯方塊的消除過程 ,這樣經過一段時間的嘗試數據內容就可能被全部搞清楚,由於這種風險的存在才研發出更安全的壓縮算法。

C.HPACK算法

2.0版本中HPACK算法在C/S中使用 首部表 來存儲之前發送的鍵值對,對於相同的數據通信期間幾乎不會改變的通用鍵值對只需發送一次即可。

極端情況如果請求頭每次沒有變化,那麼傳輸中則不包含首部,也就是首部開銷就是

零字節 。如果首部鍵值對發生變化了,也只需要發送變化的數據,並且將 新增或修改的首部幀會被追加到首部表 ,首部表在鏈接存活期始終存在, 並且由客戶端和服務器 共同更新和維護

簡單說就是客戶端和服務端共同維護了一個 key-value 的結構,發生變化時則更新傳輸,否則就不傳輸,這樣相當於 首次全量傳輸之後增量更新傳輸 即可,這個思想在日常開發中也非常普遍,不用想的太複雜。

如圖展示了首部表的更新過程 ( 圖片來自參考4 ) :

理解TCP/IP協議棧之HTTP2.0

hpack算法的相關文檔:

<code>https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12/<code>

3.5 服務端推送

服務端推送是2.0版本新增的一個強大功能,和一般的 一問一答 式的C/S交互不同, 推送式交互中服務器可以對客戶端的一個請求發送多個響應 ,除了對最初請求的響應外還向客戶端推送額外資源,無需客戶端明確地請求也可以推送。

舉個栗子:

想象一下你去餐廳吃飯,服務好的快餐廳在你點好一份牛肉麵之後,還會給你送上餐巾紙、筷子、勺子甚至調料等,這樣主動式的服務,節約了客人的時間並且提高了用餐體驗。

在實際的C/S交互中這種 主動推送額外資源 的方法很有效,因為幾乎每個網絡應用都會包含多種資源,客戶端需要全部逐個獲取它們,此時如果讓服務器提前推送這些資源,從而可以 有效減少額外的延遲時

,因為服務器可以知道客戶端下一步要請求什麼資源。

如圖為服務端推送的簡單過程 ( 圖片來自參考4 ) :

理解TCP/IP協議棧之HTTP2.0

4. 總結

本文通過介紹Http協議的歷史演進、各個版本的主要特徵和優缺點、重點介紹了Http2.0協議的一些特性,包括: SPDY協議、二進制分幀協議、多路複用、首部壓縮、服務端推送 等重要功能, 篇幅有限不能展開太多 。

雖然http2.0版本協議有很多非常優秀的功能並且在 2015年正式發佈 ,現在國內外一些大廠基本都有使用http2.0承擔部分請求,但是目前仍 然未廣泛普及

目前http3.0版本在2018年也推出來了,至於http2.0和http3.0的推廣和普及是需要時間的,但是堅信我們的網絡可以 更安全、更快捷、更節約


分享到:


相關文章: