HTTP2.0的奇妙日常

jopen 9年前發布 | 25K 次閱讀 HTTP2

【交代:時間是在距今的5年后,由于我的智能滑板鞋,還有智能小內內的創業失敗,為了在這個先看胸再看臉的時代活下去,我不得不重操舊業,去面試web前端工程師的工作。多年沒有接觸web開發了,找了個AlloyTeam的老同事晨伯幫我溫習一下知識,好讓面試通過】

    

    “多年沒見,你的女神后來什么樣了”晨伯總是這么八卦我的女神,而不是我。

    “我給你一個表情,你自己體會一下”HTTP2.0的奇妙日常

    “你先寫個小頁面給我看看吧,我指導一下你吧。”晨伯一幅很吊的樣子。

但是這樣的小case當然難不了我,雖然多年沒碰web,但是我當年可以是AlloyTeam的成員啊。很快我就啪啪啪地完成了頁面。 晨伯看完我寫的頁面,一幅“我可是有女朋友的男人”的表情,感嘆了一句“現在是HTTP2.0的時代啦,給你普及一下知識點”。

HTTP2.0性能增強的核心:二進制分幀

     HTTP 2.0最大的特點: 不會改動HTTP 的語義,HTTP 方法、狀態碼、URI 及首部字段,等等這些核心概念上一如往常,卻能致力于突破上一代標準的性能限制,改進傳輸性能,實現低延遲和高吞吐量。而之所以叫2.0,是在于新增的二進制分幀層。

    既然又要保證HTTP的各種動詞,方法,首部都不受影響,那就需要在應用層(HTTP2.0)和傳輸層(TCP or UDP)之間增加一個二進制分幀層。

    在二進制分幀層上, HTTP 2.0 會將所有傳輸的信息分割為更小的消息和幀,并對它們采用二進制格式的編碼 ,其中HTTP1.x的首部信息會被封裝到Headers幀,而我們的request body則封裝到Data幀里面。

HTTP2.0的奇妙日常



然后,HTTP 2.0 通信都在一個連接上完成,這個連接可以承載任意數量的雙向數據流。相應地,每個數據流以消息的形式發送,而消息由一或多個幀組成,這些幀可以亂序發送,然后再根據每個幀首部的流標識符重新組裝。
</div>

    當他侃侃而談的時候,大概是這個樣子的,你們也來感受一下。 HTTP2.0的奇妙日常

    “聽起來好屌的樣子,但是那樣,所有的二進制幀都會帶上Headers幀,這是多大的數據冗余傳送啊,性能會多….”我疑問道。

    HTTP2.0的奇妙日常“還沒講完呢,插什么嘴!”(哎呀我差!我這么帥,可別打臉啊。)

    

HTTP2.0 首部壓縮

    HTTP 2.0 在客戶端和服務器端使用“首部表”來跟蹤和存儲之前發送的鍵-值對,對于相同的數據,不再通過每次請求和響應發送;通信期間幾乎不會改變的通用鍵-值對 (用戶代理、可接受的媒體類型,等等)只 需發送一次。事實上,如果請求中不包含首部(例如對同一資源的輪詢請求),那么 首部開銷就是零字節。此時所有首部都自動使用之前請求發送的首部。

    如果首部發生變化了,那么只需要發送變化了數據在Headers幀里面,新增或修改的首部幀會被追加到“首部表”。 首部表在 HTTP 2.0 的連接存續期內始終存在,由客戶端和服務器共同漸進地更新 。

</div>

    “好了,現在你倒是給我解釋一下,這里使用自動化合并文件和Sprite合圖是什么回事?”晨伯不解

    “本質上,當然是為了減少請求啦,通過多個js或css合并成一個文件,多張小圖片拼合成Sprite圖,可以讓多個HTTP請求減少為一個,減少額外的協議開銷,而提升性能。”如是道也

    “當然,一個HTTP的請求的body太大也是不合理的,有個度。文件的合并也會犧牲模塊化和緩存粒度,可以把“穩定”的代碼or 小圖 合并為一個文件or一張Sprite,讓其充分地緩存起來,從而區分開迭代快的文件” 我不明白晨伯的問題,就稍微補充了一下方案。


   晨伯起來又HTTP2.0的奇妙日常,略疼,略疼。話說多年的程序員交流都用這種肢體動作了嗎? 


所有的HTTP2.0的請求都在一個TCP鏈接上

    HTTP2.0所有通信都是在一個TCP連接上完成。HTTP 2.0 把 HTTP 協議通信的基本單位縮小為一個一個的幀,這些幀對應 著邏輯流中的消息。并行地在同一個 TCP 連接上雙向交換消息。就好比,我請求一個頁面http://www.qq.com。頁面上所有的資源請求都是客戶端與服務器上的一條TCP上請求和響應的!

    有關注TCP性能的同學就會知道,HTTP性能的關鍵在于低延遲而不是高帶寬! 大多數HTTP 連接的時間都很短,而且是突發性的,但TCP 只在長時間連接傳輸大塊數據時效率才最高。HTTP 2.0 通過讓所有數據流共用同一個連接,可以更有效地使用TCP 連接,讓高帶寬也能真正的服務于HTTP的性能提升。


    同時,單鏈接多資源的方式,使到至上而下的層面都得到了好處:

    1. 可以減少服務鏈接壓力,內存占用少了,連接吞吐量大了

    2. 由于 TCP 連接減少而使網絡擁塞狀況得以改觀;

    3. 慢啟動時間減少,擁塞和丟包恢復速度更快。

也就是說,“資源合并減少請求”的優化手段對于HTTP2.0來說是沒有效果的,只會增大無用的工作量而已。

他說得好有道理,我竟然掩臉而對(因為臉被打疼了)。

“你在再我說說,這些cdn1.cn,cdn2.cn,cdn3.cn是什么回事啊”晨伯又問到。

“因為HTTP1.x上如果一個只用一個持久鏈接,請求只能一個一個順序請求,為了高效地并行下載資源,瀏覽器允許我們打開多個TCP會話,但是一個域名下限制6個鏈接。為了突破這些限制,我們可以域名分區,提高并行下載資源能力…..”我只好把我當年知道的說出來

當時我就有預感要HTTP2.0的奇妙日常,而晨伯總是按套路出牌….

并行雙向字節流的請求和響應

    在HTTP2.0上,客戶端和服務器可以把HTTP 消息分解為互不依賴的幀,然后亂序發送,最后再在另一端把它們重新組合起來。注意,同一鏈接上有多個不同方向的數據流在傳輸。客戶端可以一邊亂序發送 stream,也可以一邊接收者服務器的響應,而服務器那端同理。

HTTP2.0的奇妙日常


把 HTTP 消息分解為獨立的幀,交錯發送,然后在另一端重新組裝是 HTTP 2.0 最 重要的一項增強。事實上,這個機制會在整個 Web 技術棧中引發一系列連鎖反應, 從而帶來巨大的性能提升,因為:

可以并行交錯地發送請求,請求之間互不影響;

可以并行交錯地發送響應,響應之間互不干擾;

只使用一個連接即可并行發送多個請求和響應;

消除不必要的延遲,從而減少頁面加載的時間;

</div>

那么也就是說“域名分區”這種優化手段對于HTTP2.0是無用的,因為資源都是并行交錯發送,且沒有限制,不需要額外的多域名并行下載。

“既然所有資源都是并行交錯發送,會不會出現這樣的情況【瀏覽器明明在等關鍵的 CSS 和JS,你TMD的服務器還在發送圖片】” 我疑問道。

晨伯又HTTP2.0的奇妙日常。我開始確信,這是多年后程序員的肢體禮儀方式。

HTTP2.0的請求優先級

    每個HTTP2.0流里面有個優先值,這個優先值確定著客戶端和服務器處理不同的流采取不同的優先級策略,高優先級的流都應該優先發送,但又不會絕對的。 絕對地準守,可能又會引入首隊阻塞的問題:高優先級的請求慢導致阻塞其他資源交付。分配處理資源和客戶端與服務器間的帶寬,不同優先級的混合也是必須的。

“有了優先級,HTTP2.0根本不會發生【瀏覽器明明在等關鍵的 CSS 和JS,你TMD的服務器還在發送黃圖】”晨伯道。

“我根本沒有說是服務器在發黃圖,好不好。”我吐槽了一下。

  “還有還有,你這里的一段base64內嵌圖片又是什么回事?是黃圖嗎?” 晨伯又挑戰我了。

內嵌圖片這種,有使用條件的優化手段,我還是不要說話好,不然的話按照這個故事的尿性,他應該又要飛拳我。

HTTP2.0的服務器推送

    HTTP 2.0 新增的一個強大的新功能,就是服務器可以對一個客戶端請求發送多個響應。換句話說,服務器可以強奸你的瀏覽器,哦不,應該是,除了對最初請求的響應外,服務器還可以額外向客戶端推送資源,而無需客戶端明確地請求。

當瀏覽器請求一個html,服務器其實大概知道你是接下來要請求資源了,而不需要等待瀏覽器得到html后解析頁面再發送資源請求。我們常用的內嵌圖片也可以理解為一種強制的服務器推送:我請求html,卻內嵌了張黃圖。

    有了HTTP2.0的服務器推送,HTTP1.x時代的內嵌資源的優化手段也變得沒有意義了。而且使用服務器推送的資源的方式更加高效,因為客戶端還可以 緩存起來,甚至可以由不同的頁面共享(依舊遵循同源策略)。當然,你是個正直的瀏覽器,是可以決絕服務器推送的黃圖的。

    不知道為什么,說到黃圖這個家伙就興奮起來了,再也沒有打我了。然后交談就變成了16+周歲的少女不宜收聽的內容了。不過HTTP2.0的知識收獲了不少。

到了我要面試的日子了,互聯網公司A果真要(筆試|鄙視)一下我。我寫出了下面的頁面

 HTTP2.0的奇妙日常


</div>

在場面試官,紛紛鼓掌站了起來,“如此高效的頁面,難得啊~你被錄取了!”。

這看著這份如同我前端實習時候寫的頁面,我心中默默感嘆“十年前端,終歸如初”。

出于禮貌,我想起了晨伯教我的新式前端工程師肢體禮儀,然后…..

參考:

來自:http://www.alloyteam.com/2015/03/http2-0-di-qi-miao-ri-chang/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!