http/2.0時代已經來臨了!


知識分享  文章轉自:https://blog.csdn.net/g6U8W7p06dCO99fQ3/article/details/78906348

 

    現在是資源共享的時代,同樣也是知識分享的時代,如果你覺得本文能學到知識,請把知識與別人分享!

開篇HTTP發展的心路歷程

 

640?wx_fmt=png&wxfrom=5&wx_lazy=1

上圖:連接無法復用

640?wx_fmt=png&wxfrom=5&wx_lazy=1

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

640?wx_fmt=png

上圖:HTTPpipelining:建立多個連接

640?wx_fmt=png

上圖:多路復用

先對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服務器根據接收到的請求后,向客戶端發送響應信息。

 

640?wx_fmt=png

 

HTTP 協議的版本

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

 

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

 

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

 

640?wx_fmt=png

 

HTTP 1.1 做了哪些升級:

 

  • 緩存處理,在HTTP1.0中主要使用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連接成功)狀態,完成三次握手。

 

完成三次握手,客戶端與服務器開始傳送數據。

 

640?wx_fmt=png

 

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

 

    由於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。 

 

640?wx_fmt=png

 

瀏覽器阻塞(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);

 

640?wx_fmt=png

 

多路復用 (Multiplexing)

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

 

請求優先級

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

  • 服務器可以根據流的優先級,控制資源分配(CPU、內存、帶寬),而在響應數據准備好之后,優先將最高優先級的幀發送給客戶端。

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

 

header壓縮

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

 

服務端推送

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

  • HTTP 2.0 連接后,客戶端與服務器交換SETTINGS 幀,借此可以限定雙向並發的流的最大數量。

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

  • 服務器必須遵循請求- 響應的循環,只能借着對請求的響應推送資源

 

服務器推送到底是什么?

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

 

普通的客戶端請求過程:

640?wx_fmt=png

 

服務端推送的過程:

640?wx_fmt=png

 

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

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

 

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

 

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

 

640?wx_fmt=png  

 

如何應用到自己的項目里

    現有的任何網站和應用,無需做任何修改都可以在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會自動向下兼容的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM