雜談:HTTP1.1 與 HTTP2.0 知多少?

HTTP是應用層協議,是基於TCP底層協議而來。

TCP的機制限定,每建立一個連接需要3次握手,斷開連接則需要4次揮手。

HTTP協議採用“請求-應答”模式,HTTP1.0下,HTTP1.1非Keep-Alive模式下,每個請求都要新建一個連接,完成之後立即斷開連接。如果有新的請求,則要重新創建請求連接(HTTP協議為無連接的協議)。

這樣不免造成了網絡傳輸數據一定的延遲,1999年推出HTTP1.1,雖然可以通過設置延遲時間,讓連接延遲關閉。但仍然有線頭阻塞,max-connection最大連接限制了並行請求數量等痛點,難以應對日益增長的大數據實時傳輸。

新一代HTTP2.0協議應運而生,提高HTTP應對高併發場景下的數據傳輸能力。

雜談:HTTP1.1 與 HTTP2.0 知多少?

雜談:HTTP1.1 與 HTTP2.0 知多少?

「 HTTP1.1」

Pipelining管道化

提出管道化方案解決連接延遲,服務端可設置Keep-Alive來讓連接延遲關閉時間,但因為瀏覽器自身的Max-Connection最大連接限制,同一個域名 (host) 下的請求連接限制(同域下谷歌瀏覽器是一次限制最多6個連接),只能通過多開域名來實現,這也就是我們的靜態資源選擇放到CDN上或其它域名下,來提高資源加載速度。

pipelining方案需要前後端支持,但絕大部分的HTTP代理器對pipelining的支持並不友好。

只支持GET/HEAD

pipelining只支持GET/HEAD方式傳送數據,不支持POST等其它方式傳輸。

頭部信息冗餘

HTTP是無狀態的,客戶端/服務端只能通過HEAD的數據維護獲取狀態信息,這樣就造成每次連接請求時都會攜帶大量冗餘的頭部信息,頭部信息包括COOKIE信息等。

超文本協議

HTTP1.X是超文本協議傳輸。超文本協議傳輸,發送請求時會找出數據的開頭和結尾幀的位置,並去除多餘空格,選擇最優方式傳輸。如果使用了HTTPS,那麼還會對數據進行加密處理,一定程度上會造成傳輸速度上的損耗。

線頭阻塞

pipelining通過延遲連接關閉的方案,雖然可同時發起對服務端的多個請求,但服務端的response依舊遵循FIFO(first in first out)規則 依次返回。

舉個例子客戶端發送了1、2、3、4四個請求,如果1沒返回給客戶端,那麼2,3,4也不會返回。這就是所謂的線頭阻塞。高併發高延遲的場景下阻塞明顯。

HTTP1.X傳輸優化方法

  1. 多個資源合併成一個請求連接,如前端Spriting雪碧圖,JS/CSS壓縮成一個文件等
  2. Inlining內聯的方式,採用inline css/inline js等併入html中,減少對css/js文件的請求
  3. CDN資源多域名轉發,靜態資源分佈存儲在多個域下。

以上三種三種方法雖然能使HTTP1.X協議傳輸速度提高,但也有對應的不足。

  1. 如雪碧圖,將多個小圖合併成一張大圖,降低多張小圖請求的高延遲,但是如果我只想要兩個icon小圖,卻需要加載一整張大圖,就會造成資源冗餘。合併的JS/CSS文件也有類似的問題。
  2. 內聯的方式,會讓我們的代碼變得難以維護,讓html文件變得更大,代碼混合嚴重。
  3. 多域名下可緩解Max-Connection,但不同域會讓Cookie信息無法彼此共享。

瞭解完HTTP1.1的痛點,接下來就是我們新一代的HTTP協議HTTP2.0


「 HTTP2.0」

前身SPDY

SPDY是2012年穀歌推出的是基於SSL/TLS的傳輸協議,SPDY有降低延遲,多路複用,頭部壓縮,服務端推送等特點,這些特點也稱為了後續HTTP2.0的功能基石,HTTP2.0是SPDY/3 draft的優化版。

HTTP2.0 與 SPDY的區別:

  1. HTTP2.0 頭部壓縮採用HPACK, 而SPDY採用DELEFT。
  2. HTTP2.0 理論上支持明文HTTP傳輸,而SPDY強制使用HTTPS。

多路複用

(一個域只要一個TCP連接)實現真正的併發請求,降低延時,提高了帶寬的利用率。

頭部壓縮

客戶端/服務端進行漸進更新維護,採用HPACK壓縮,節省了報文頭佔用流量。

  1. 相同的頭部信息不會通過請求發送,延用之前請求攜帶的頭部信息。
  2. 新增/修改的頭部信息會被加入到HEAD中,兩端漸進更新。

兩端會共同維護一個head list,每次請求時都會進行檢查。

該list包括:

  1. static (既定的頭部信息)
  2. dynamic (自定義的頭部信息)

請求優先級

每個流都有自己的優先級別,客戶端可指定優先級。並可以做流量控制。因為HTTP2.0的傳世允許請求併發,但是應用場景中我們要處理一些主要文件的優先級權重,以及資源模塊依賴等。所以我們可通過設置優先級來提高主要文件的權重,使其優先加載請求。

服務端推送

請求不是來自客戶端“明確”的請求,是從服務端PUSH_PROMISE幀中提供。例如我們加載index.html, 我們可能還需要index.js, index.css等文件。傳統的請求只有當拿到index.html,解析html中對index.js/index.css的引入才會再請求資源加載,但是通過服務端數據,可以提前將資源推送給客戶端,這樣客戶端要用到的時候直接調用即可,不用再發送請求。

  • push的資源能緩存在瀏覽器中
  • 不同的網頁能使用該緩存,不用重新發起
  • push的資源通過multiplexed進行傳輸
  • push的資源能夠進行priority標識
  • client有權取消push資源的加載
  • push的資源必須同域

二進制協議

HTTP2.0 傳輸協議採用二進制協議,區別與HTTP1.X的超文本協議。更易於幀,數據包的發送接收。HTTP2.0是運行在TCP連接上的應用層協議,接受服務器或發送請求時,會自動將頭部信息/request body分成HEAD幀和DATA幀。

客戶端/服務端發送/接收數據時,會將數據打散亂序發送,接收數據時接收一端再通過streamID標識來將數據合併。

HTTP2.0環境要求

HTTP2.0理論上支持明文HTTP傳輸,但因為其前身SPDY是在TLS上,他們的主人Google 和 Firefox 都支持TLS架構,所以需要搭建HTTP2.0 + TLS成了標準。

  1. Nginx > 1.10
  2. OpenSSL > 1.0.2
  3. CA證書


分享到:


相關文章: