HTTP是應用層協議,是基於TCP底層協議而來。css
TCP的機制限定,每創建一個鏈接須要3次握手,斷開鏈接則須要4次揮手。html
HTTP協議採用「請求-應答」模式,HTTP1.0下,HTTP1.1非Keep-Alive模式下,每一個請求都要新建一個鏈接,完成以後當即斷開鏈接。若是有新的請求,則要從新建立請求鏈接(HTTP協議爲無鏈接的協議)。前端
這樣難免形成了網絡傳輸數據必定的延遲,1999年推出HTTP1.1,雖然能夠經過設置延遲時間,讓鏈接延遲關閉。但仍然有線頭阻塞,max-connection最大鏈接限制了並行請求數量等痛點,難以應對日益增加的大數據實時傳輸。segmentfault
新一代HTTP2.0協議應運而生,提升HTTP應對高併發場景下的數據傳輸能力。後端
提出管道化方案解決鏈接延遲,服務端可設置Keep-Alive來讓鏈接延遲關閉時間,但由於瀏覽器自身的Max-Connection最大鏈接限制,同一個域名 (host) 下的請求鏈接限制(同域下谷歌瀏覽器是一次限制最多6個鏈接),只能經過多開域名來實現,這也就是咱們的靜態資源選擇放到CDN上或其它域名下,來提升資源加載速度。瀏覽器
pipelining方案須要先後端支持,但絕大部分的HTTP代理器對pipelining的支持並不友好。緩存
pipelining只支持GET/HEAD方式傳送數據,不支持POST等其它方式傳輸。服務器
HTTP是無狀態的,客戶端/服務端只能經過HEAD的數據維護獲取狀態信息,這樣就形成每次鏈接請求時都會攜帶大量冗餘的頭部信息,頭部信息包括COOKIE信息等。網絡
HTTP1.X是超文本協議傳輸。超文本協議傳輸,發送請求時會找出數據的開頭和結尾幀的位置,並去除多餘空格,選擇最優方式傳輸。若是使用了HTTPS,那麼還會對數據進行加密處理,必定程度上會形成傳輸速度上的損耗。架構
pipelining經過延遲鏈接關閉的方案,雖然可同時發起對服務端的多個請求,但服務端的response依舊遵循FIFO(first in first out)規則 依次返回。
舉個例子客戶端發送了一、二、三、4四個請求,若是1沒返回給客戶端,那麼2,3,4也不會返回。這就是所謂的線頭阻塞。高併發高延遲的場景下阻塞明顯。
以上三種三種方法雖然能使HTTP1.X協議傳輸速度提升,但也有對應的不足。
瞭解完HTTP1.1的痛點,接下來就是咱們新一代的HTTP協議HTTP2.0
SPDY是2012年穀歌推出的是基於SSL/TLS的傳輸協議,SPDY有下降延遲,多路複用,頭部壓縮,服務端推送等特色,這些特色也稱爲了後續HTTP2.0的功能基石,HTTP2.0是SPDY/3 draft的優化版。
HTTP2.0 與 SPDY的區別:
(一個域只要一個TCP鏈接)實現真正的併發請求,下降延時,提升了帶寬的利用率。
客戶端/服務端進行漸進更新維護,採用HPACK壓縮,節省了報文頭佔用流量。
兩端會共同維護一個head list,每次請求時都會進行檢查。
該list包括:
每一個流都有本身的優先級別,客戶端可指定優先級。並能夠作流量控制。由於HTTP2.0的傳世容許請求併發,可是應用場景中咱們要處理一些主要文件的優先級權重,以及資源模塊依賴等。因此咱們可經過設置優先級來提升主要文件的權重,使其優先加載請求。
請求不是來自客戶端「明確」的請求,是從服務端PUSH_PROMISE幀中提供。例如咱們加載index.html, 咱們可能還須要index.js, index.css等文件。傳統的請求只有當拿到index.html,解析html中對index.js/index.css的引入纔會再請求資源加載,可是經過服務端數據,能夠提早將資源推送給客戶端,這樣客戶端要用到的時候直接調用便可,不用再發送請求。
HTTP2.0 傳輸協議採用二進制協議,區別與HTTP1.X的超文本協議。更易於幀,數據包的發送接收。HTTP2.0是運行在TCP鏈接上的應用層協議,接受服務器或發送請求時,會自動將頭部信息/request body分紅HEAD幀和DATA幀。
客戶端/服務端發送/接收數據時,會將數據打散亂序發送,接收數據時接收一端再經過streamID標識來將數據合併。
HTTP2.0理論上支持明文HTTP傳輸,但由於其前身SPDY是在TLS上,他們的主人Google 和 Firefox 都支持TLS架構,因此須要搭建HTTP2.0 + TLS成了標準。
參考文檔
做者:以樂之名 本文原創,有不當的地方歡迎指出。轉載請指明出處。