歡迎光臨
每天分享高質量文章

http2.0的時代真的來了…

來自:互扯程式(微訊號:chat_routine)

作者:互扯程式,某網際網路公司P8級專家攻城獅,曾參與過央視全臺網的研發工作。目前正在做車聯網專案的雲平臺的架構設計與研發工作。平時喜歡打球游泳,偶爾發表一些技術文章。

開篇HTTP發展的心路歷程

上圖:連線無法復用

上圖:設定Connection:Keep-Alive,保持連線在一段時間內不斷開。

上圖:HTTPpipelining:建立多個連線

上圖:多路復用

先對HTTP協議進行簡單介紹

  1. HTTP協議 :Hyper Text Transfer Protocol(超文字傳輸協議),是用於從全球資訊網(WWW:World Wide Web )伺服器傳輸超文字到本地瀏覽器的傳送協議。是網際網路上應用最為廣泛的一種網路協議。所有的WWW檔案都必須遵守這個標準。

  2. HTTP是一個基於TCP/IP通訊協議來傳遞資料(HTML 檔案, 圖片檔案, 查詢結果等)。

  3. HTTP是一個屬於應用層的面向物件的協議,由於其簡捷、快速的方式,適用於分散式超媒體資訊系統。它於1990年提出,經過幾年的使用與發展,得到不斷地完善和擴充套件。

  4. HTTP協議工作於客戶端-服務端架構為上。瀏覽器作為HTTP客戶端透過URL向HTTP服務端即WEB伺服器傳送所有請求。Web伺服器根據接收到的請求後,向客戶端傳送響應資訊。

HTTP 協議的版本

  1. HTTP 0.9作為HTTP協議的第一個版本。是非常弱的。請求(Request)只有一行,比如: GET www.leautolink.com

  2. HTTP1.0最早在網頁中使用是在1996年,那個時候只是使用一些較為簡單的網頁上和網路請求上。

  3. HTTP1.1則在1999年才開始廣泛應用於現在的各大瀏覽器網路請求中,同時HTTP1.1也是當前使用最為廣泛的HTTP協議。

HTTP 1.1 做了哪些升級:

  • 快取處理,在HTTP1.0中主要使用essay-header裡的If-Modified-Since,Expires來做為快取判斷的標準,HTTP1.1則引入了更多的快取控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供選擇的快取頭來控制快取策略。

  • 頻寬最佳化及網路連線的使用,HTTP1.0中,存在一些浪費頻寬的現象,例如客戶端只是需要某個物件的一部分,而伺服器卻將整個物件送過來了,並且不支援斷點續傳功能,HTTP1.1則在請求頭引入了range頭域,它允許只請求資源的某個部分,即傳回碼是206(Partial Content),這樣就方便了開發者自由的選擇以便於充分利用頻寬和連線。

  • 錯誤通知的管理,在HTTP1.1中新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生衝突;410(Gone)表示伺服器上的某個資源被永久性的刪除。

  • Host頭處理,在HTTP1.0中認為每臺伺服器都系結一個唯一的IP地址,因此,請求訊息中的URL並沒有傳遞主機名(hostname)。但隨著虛擬主機技術的發展,在一臺物理伺服器上可以存在多個虛擬主機(Multi-homed Web Servers),並且它們共享一個IP地址。HTTP1.1的請求訊息和響應訊息都應支援Host頭域,且請求訊息中如果沒有Host頭域會報告一個錯誤(400 Bad Request)。

  • 長連線,HTTP 1.1支援長連線(PersistentConnection)和請求的流水線(Pipelining)處理,在一個TCP連線上可以傳送多個HTTP請求和響應,減少了建立和關閉連線的消耗和延遲,在HTTP1.1中預設開啟Connection: keep-alive,一定程度上彌補了HTTP1.0每次請求都要建立連線的缺點。

如何建立連線(三次握手)


HTTP 是基於 TCP 協議的,瀏覽器最快也要在第三次握手時才能捎帶 HTTP 請求報文,達到真正的建立連線,但是這些連線無法復用會導致每次請求都經歷三次握手和慢啟動。三次握手在高延遲的場景下影響較明顯,慢啟動則對檔案類大請求影響較大。

  • 第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,併進入SYN_SENT狀態,等待伺服器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。

  • 第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;

  • 第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED(TCP連線成功)狀態,完成三次握手。

完成三次握手,客戶端與伺服器開始傳送資料。

如何關閉連線(四次揮手):

由於TCP連線是全雙工的,因此每個方向都必須單獨進行關閉。這個原則是當一方完成它的資料傳送任務後就能傳送一個FIN來終止這個方向的連線。收到一個 FIN只意味著這一方向上沒有資料流動,一個TCP連線在收到一個FIN後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

TCP的連線的拆除需要傳送四個包,因此稱為四次揮手(four-way handshake)。客戶端或伺服器均可主動發起揮手動作,在socket程式設計中,任何一方執行close()操作即可產生揮手操作。

  1. 客戶端A傳送一個FIN,用來關閉客戶A到伺服器B的資料傳送。 

  2. 伺服器B收到這個FIN,它發回一個ACK,確認序號為收到的序號加1。和SYN一樣,一個FIN將佔用一個序號。 

  3. 伺服器B關閉與客戶端A的連線,傳送一個FIN給客戶端A。 

  4. 客戶端A發回ACK報文確認,並將確認序號設定為收到序號加1。 

瀏覽器阻塞(HOL blocking):

瀏覽器對於同一個域名,一般PC端瀏覽器會針對單個域名的server同時建立6~8個連線,手機端的連線數則一般控制在4~6個(這個根據瀏覽器核心不同可能會有所差異),超過瀏覽器最大連線數限制,後續請求就會被阻塞。

在講HTTP/2之前我們先來說說SPDY

SPDY協議是Google提出的基於傳輸控制協議(TCP)的應用層協議,透過壓縮多路復用優先順序來縮短載入時間。該協議是一種更加快速的內容傳輸協議,於2009 年年中釋出。

GoogleChrome、MozillaFirefox以及Opera已預設開啟SPDY。Google曾經稱它的測試顯示,頁面載入提高了一倍。該協議是一種更加快速的內容傳輸協議。

SPDY協議設定的標的


    1. 頁面載入時間(PLT,Page • Load Time)降低 50%;

    2. 無需網站作者修改任何內容;

    3. 最小化配置複雜度,無需變更網路基礎設施;

註:為了達到降低50% 頁面載入時間的標的,SPDY 引入了一個新的二進位制分幀資料層,以實現多向請求和響應、優先次序、最小化及消除不必要的網路延遲,目的是更有效地利用底層TCP 連線;

HTTP/2:SPDY的升級版

  • HTTP-WG(HTTP Working Group)在2012 年初把HTTP 2.0提到了議事日程,吸取SPDY 的經驗教訓,併在此基礎上制定官方標準。

  • HTTP/2 的主要標的是改進傳輸效能,更有效地利用網路資源,實現低延遲和高吞吐量。從另一方面看,HTTP 的高層協議語意並不會因為這次版本升級而受影響。所有HTTP 首部、值,以及它們的使用場景都不會變。

  • HTTP/2 致力於突破上一代標準眾所周知的效能限制,但它也是對之前1.x 標準的擴充套件,而非替代。之所以要遞增一個大版本到2.0,主要是因為它改變了客戶端與伺服器之間交換資料的方式

HTTP/2 是如何提高效率呢?

二進位制分幀:HTTP 2.0 的所有幀都採用二進位制編碼


  • :客戶端與伺服器透過交換幀來通訊,幀是基於這個新協議通訊的最小單位。

  • 訊息:是指邏輯上的 HTTP 訊息,比如請求、響應等,由一或多個幀組成。

  • :流是連線中的一個虛擬通道,可以承載雙向的訊息;每個流都有一個唯一的整數識別符號(1、2…N);

多路復用 (Multiplexing)


多路復用允許同時透過單一的 HTTP/2 連線發起多重的請求-響應訊息。有了新的分幀機制後,HTTP/2 不再依賴多個TCP 連線去實現多流並行了。每個資料流都拆分成很多互不依賴的幀,而這些幀可以交錯(亂序傳送),還可以分優先順序。最後再在另一端把它們重新組合起來。HTTP 2.0 連線都是持久化的,而且客戶端與伺服器之間也只需要一個連線(每個域名一個連線)即可。 

請求優先順序


  • 把HTTP 訊息分解為很多獨立的幀之後,就可以透過最佳化這些幀的交錯和傳輸順序,每個流都可以帶有一個31 位元的優先值:0 表示最高優先順序;2的31次方-1 表示最低優先順序。

  • 伺服器可以根據流的優先順序,控制資源分配(CPU、記憶體、頻寬),而在響應資料準備好之後,優先將最高優先順序的幀傳送給客戶端。

  • HTTP 2.0 一舉解決了所有這些低效的問題:瀏覽器可以在發現資源時立即分派請求,指定每個流的優先順序,讓伺服器決定最優的響應次序。這樣請求就不必排隊了,既節省了時間,也最大限度地利用了每個連線。


essay-header壓縮


HTTP1.x的essay-header帶有大量資訊,而且每次都要重覆傳送,HTTP/2使用encoder來減少需要傳輸的essay-header大小,通訊雙方各自cache一份essay-header fields表,既避免了重覆essay-header的傳輸,又減小了需要傳輸的大小。

服務端推送


  • 伺服器可以對一個客戶端請求傳送多個響應。伺服器向客戶端推送資源無需客戶端明確地請求。

  • HTTP 2.0 連線後,客戶端與伺服器交換SETTINGS 幀,藉此可以限定雙向併發的流的最大數量。

  • 所有推送的資源都遵守同源策略。換句話說,伺服器不能隨便將第三方資源推送給客戶端,而必須是經過雙方確認才行。

  • 伺服器必須遵循請求- 響應的迴圈,只能藉著對請求的響應推送資源

伺服器推送到底是什麼?


服務端推送能把客戶端所需要的資源伴隨著index.html一起傳送到客戶端,省去了客戶端重覆請求的步驟。正因為沒有發起請求,建立連線等操作,所以靜態資源透過服務端推送的方式可以極大地提升速度。

普通的客戶端請求過程:


服務端推送的過程:

HTTP/2的多路復用和HTTP1.1中的長連線復用有什麼區別?


  • HTTP/1.0 一次請求-響應,建立一個連線,用完關閉;每一個請求都要建立一個連線;

  • HTTP/1.1 Pipeling解決方式為,若干個請求排隊序列化單執行緒處理,後面的請求等待前面請求的傳回才能獲得執行機會,一旦有某請求超時等,後續請求只能被阻塞,毫無辦法,也就是人們常說的線頭阻塞;

  • HTTP/2多個請求可同時在一個連線上並行執行。某個請求任務耗時嚴重,不會影響到其它連線的正常執行;

  

如何應用到自己的專案裡

現有的任何網站和應用,無需做任何修改都可以在HTTP 2.0 上跑起來。不用為了利用HTTP 2.0 的好處而修改標記。HTTP 伺服器必須執行HTTP 2.0 協議,但大部分使用者都不會因此而受到影響。


如果你使用NGINX,只要在配置檔案中啟動相應的協議就可以了,可以參考NGINX白皮書,NGINX配置HTTP2.0官方指南。


使用了HTTP2.0那麼,原本的HTTP1.x怎麼辦,這個問題其實不用擔心,HTTP2.0完全相容HTTP1.x的語意,對於不支援HTTP2.0的瀏覽器,NGINX會自動向下相容的。


●本文編號328,以後想閱讀這篇文章直接輸入328即可

●輸入m獲取文章目錄

推薦↓↓↓

前端開發

更多推薦18個技術類微信公眾號

涵蓋:程式人生、演演算法與資料結構、駭客技術與網路安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

贊(0)

分享創造快樂