HTTP/2.0的前世今生

Mrlgm發表於2019-03-14

前記

http協議是前端經常打交道的協議之一,發展至今已經到了2.0版本,這兩天我刷完了《圖解HTTP》,讓我對與HTTP協議的發展史有了更深層的瞭解

全球資訊網的出現和HTTP的誕生

時間要回到1989年的聖誕節,那一天李爵士發明了世界上第一個網頁瀏覽器WorldWideWeb(同時也是網頁編輯器)和第一個網頁伺服器。為了在網頁瀏覽器和網頁伺服器中傳輸文字資訊,李爵士將超文字嫁接到因特網上(超文字的概念並不是李爵士提出來的),由此誕生了超文字標記語言(HTML)

為了在全球資訊網中釋出和接收HTML,李爵士發明了超文字傳輸協議協議,也就是HTTP的誕生

最初的HTTP/0.9

1991年,李爵士釋出文章標誌著全球資訊網公共專案的開始。在建立HTTP標準規範時,制定者主要想把HTTP當作傳輸HTML文件的協議,所以起初的協議非常簡單。

請求由單行指令構成,以唯一可用方法GET開頭,其後跟目標資源的路徑(一旦連線到伺服器,協議、伺服器、埠號這些都不是必須的)。

GET /mypage.html

響應也極其簡單的:只包含響應文件本身。

<HTML>這是一個非常簡單的HTML頁面</HTML>

跟後來的版本不同,HTTP/0.9的響應內容並不包含HTTP頭,這意味著只有HTML檔案可以傳送,無法傳輸其他型別的檔案;也沒有狀態碼或錯誤程式碼:一旦出現問題,一個特殊的包含問題描述資訊的HTML檔案將被髮回,供人們檢視。

這時的HTTP協議,伺服器傳送完畢後就會關閉TCP連線

升級之後的HTTP/1.0

由於 HTTP/0.9 協議的應用十分有限,瀏覽器和伺服器的迅速發展和擴充套件,使其已經不能夠滿足需要,所以,1996年5月,HTTP協議的1.0版本釋出,這次釋出的內容並沒有被納入標準,而是為1.1版本的構建可擴充套件性的嘗試,更新的內容也非常多,主要有

  • 協議版本資訊現在會隨著每個請求傳送(HTTP/1.0被追加到了GET行)
  • 狀態碼會在響應開始時傳送,使瀏覽器能瞭解請求執行成功或失敗,並相應調整行為(如更新或使用本地快取)
  • 引入了HTTP頭的概念,無論是對於請求還是響應,允許傳輸後設資料,使協議變得非常靈活,更具擴充套件性
  • 在新HTTP頭的幫助下,具備了傳輸除純文字HTML檔案以外其他型別文件的能力(感謝Content-Type頭)

此時,HTTP的請求已經變成這樣了

GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
複製程式碼

響應變成了這樣

HTTP/1.0 200 OK 
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84

<html>
  <body>Hello World</body>
</html>
複製程式碼

此時的HTTP協議已經初具雛形,和我們現在看到的非常像,這是第一個在通訊中指定版本號的HTTP協議版本,至今仍被廣泛採用,但是它並不是沒有問題的,它仍然存在著0.9版本的問題,就是TCP連線不可以複用,每次傳送請求都需要建立TCP連線,新建成本高,還需要傳送前的預熱。所以HTTP/1.0效能較差,為了解決這個問題,有些瀏覽器在傳送請求時,使用了一個非標準的Connection欄位。

Connection: keep-alive
複製程式碼

伺服器不關閉TCP連線,以便其他請求複用,同樣回覆

Connection: keep-alive
複製程式碼

一個可以複用的TCP連線就建立了,直到客戶端或伺服器主動關閉連線。但是,這不是標準欄位,不同實現的行為可能不一致,因此不是根本的解決辦法。

標準的誕生HTTP/1.1

就在HTTP/1.0釋出的幾個月後,HTTP/1.1就誕生了,這次版本它進一步完善了HTTP協議,哪怕到今天都是最流行的協議之一

HTTP/1.1 消除了大量歧義內容並引入了多項改進:

  • 連線可以複用,節省了多次開啟TCP連線載入網頁文件資源的時間。
  • 增加流水線操作,允許在第一個應答被完全傳送之前就傳送第二個請求,以降低通訊延遲。
  • 支援響應分塊。
  • 引入額外的快取控制機制。
  • 引入內容協商機制,包括語言,編碼,型別等,並允許客戶端和伺服器之間約定以最合適的內容進行交換。
  • 感謝Host頭,能夠使不同域名配置在同一個IP地址的伺服器上。

已經發展到這個時候,那麼協議完美了嗎

事實上並沒有,雖然可以複用TCP連線,並且可以在一個連線中同時傳送多個HTTP請求,但是服務端的處理是按順序的,這就造成一個請求阻塞了,那麼後面的所有請求的響應都會阻塞,這稱為"隊頭堵塞"(Head-of-line blocking)

解決方法一是減少請求數,二是同時多開持久連線。但一般瀏覽器最多同時建立六個TCP連線

消除HTTP瓶頸的SPDY

隨著時代的發展,web的用途開始變得多種多樣,比如線上購物網站、社交網路服務、企業或組織內部的各種管理工具,等等

雖然這些功能已經通過web應用和指令碼程式實現,但在效能上未必最優,這是因為HTTP協議上的限制以及自身效能有限。

以下這些HTTP標準就會成為瓶頸

  • 一條連線上服務端只可以返回一個請求
  • 請求只能從客戶端開始,客戶端不可以接收除響應以外的指令
  • 請求/響應首部未經壓縮就傳送。首部資訊越多延遲越大
  • 傳送冗長的首部。每次互相傳送相同的首部造成的浪費較多
  • 可任意選擇資料壓縮格式。非強制壓縮傳送

HTTP的功能不足可以通過建立一套全新的協議來彌補,可是目前基於HTTP協議的web瀏覽器已經遍佈全球,因此無法完全拋棄HTTP,有一些新協議的規則是基於HTTP的,並在此基礎上新增了新的功能

Google在2010年釋出了SPDY,其開發目標旨在解決HTTP的效能瓶頸,縮短Web頁面的載入時間(50%)

SPDY沒有完全改寫HTTP協議,而是在應用層和傳輸層之間通過新加會話層的形式運作。同時,考慮到安全性問題,SPDY規定通訊中使用SSL。

SPDY還是採用HTTP建立通訊連線。因此還是可以使用HTTP的GET或POST等方法、Cookie以及HTTP報文等。

HTTP獲得了以下額外的功能

  • 多路複用流
  • 賦予請求優先順序
  • 壓縮HTTP首部
  • 推送功能
  • 伺服器提示功能

SPDY解決了部分問題,但是並沒有從根本解決問題。

但這個協議在Chrome瀏覽器上證明可行以後,就被當作 HTTP/2 的基礎,主要特性都在 HTTP/2 之中得到繼承。

期盼的HTTP/2.0的誕生

HTTP/2.0的目標是改善使用者在使用Web時的速度體驗

對比HTTP/1.1,改善有如下幾點

  • HTTP/2是二進位制協議而不是文字協議。它不能再手動讀取和建立,改善的優化技術現在可被實施。
  • 這是一個複用協議。並行的請求能在同一個連結中處理,移除了HTTP/1.x中順序和阻塞的約束。
  • 頭部壓縮,因為headers在一系列請求中常常是相似的,其移除了重複和傳輸重複資料的成本。
  • 其允許伺服器在客戶端快取中填充資料,通過一個叫伺服器推送的機制來提前請求。

參考資料

阮一峰部落格 MDN 《圖解HTTP》

相關文章