HTTP是基于TCP的一個應用,本文簡要對比一下各主流HTTP協(xié)議的區(qū)別微酬。
一绘趋、各主流版本區(qū)別
主流版本如下:
- HTTP 0.9
- HTTP 1.1
- HTTP 2.0
1.1 HTTP 0.9
HTTP 1.0 默認是短鏈接颤陶,即Keep-Alive為false
,所有的請求自然也無法復用陷遮,因此每次請求都需要經(jīng)過TCP的三次握手滓走、四次揮手,效率低下帽馋。
只支持GET請求搅方。
1.2 HTTP 1.1
1.2.1 ‘長’連接
HTTP 1.1 默認開啟了連接保持,即Keep-Alive為true
茬斧,因此連接自創(chuàng)建之初會保留一段時間腰懂,直到timeout或者客戶端/服務端任意一方想要通過connection:close
進行關閉連接,針對HTTPkeep-alive
的設置项秉,請移步至此:https://devdocs.io/http/headers/keep-alive绣溜。
1.2.2 分包傳輸
提供了Transfer-Encoding
header,支持信息payload分包傳輸娄蔼,那么關于分包傳輸怖喻,請求接收端需要關注兩個參數(shù):chunk-size
、chunk-data
岁诉。一個Data會被拆分成一系列的Chunk發(fā)送锚沸,當服務接受端接到一個包的chunk-size為0時,代表所有的Chunk已經(jīng)傳輸完畢涕癣。
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
請移步至此:https://devdocs.io/http/rfc9112#section-7
1.2.3 Pipelining
HTTP支持管道方式傳輸哗蜈,進一步優(yōu)化了請求速度,多個請求可以“并行”傳輸坠韩,而不再像HTTP0.9那樣:前一個請求有響應之后才能發(fā)送下一個請求(嚴格串型)距潘。
Pipelining最大的缺陷在于:原本客戶端的串型轉(zhuǎn)移到了服務器上≈桓椋客戶端并行發(fā)送完請求之后音比,在收到服務端多個響應時,因為不知道如何將多個響應給到對應的請求氢惋,因此洞翩,這就不得不讓服務端來控制響應的發(fā)送順序了。
舉例:Request 同時發(fā)送JS文件與CSS文件請求焰望,需要服務端先返回JS文件再返回CSS文件骚亿,就算CSS文件先處理好也無法發(fā)送。
備注:Pipelining在很多瀏覽器與服務端默認不支持柿估。我猜測其確實提高了客戶端的并發(fā)循未,但是加重了服務端的處理壓力,最終的并發(fā)可能還是會受限于服務端秫舌。
1.3 HTTP 2.0
一個重要的前提:HTTP2只能應用在HTTPS協(xié)議中的妖。
1.3.1 二進數(shù)據(jù)幀
原本的HTTP文本形式都會變成二進制格式傳輸,原本的傳輸內(nèi)容也會被切割成數(shù)據(jù)幀足陨,Header部分形成Header數(shù)據(jù)幀嫂粟,Body部分形成Payload數(shù)據(jù)幀,而這些數(shù)據(jù)幀中都有一個非常重要的字段流標識符墨缘,這也為多路復用打下基礎星虹,也因此環(huán)節(jié)了HTTP對頭阻塞的現(xiàn)象。
1.3.2 多路復用
HTTP2.0與HTTP1.1的Pipelining非常相似镊讼,但是HTTP2.0緩解了Pipelining中的對頭阻塞的問題宽涌,進一步優(yōu)化了響應速度。
HTTP2.0可以使用一個TCP連接足矣蝶棋。
當有多個請求/響應時卸亮,客戶端/服務端會將每個請求/響應都拆分成多個數(shù)據(jù)幀,并且進行流標識玩裙,隨后將所有數(shù)據(jù)幀并行發(fā)送給對端(并行發(fā)送兼贸,不在乎順序,這是與Pipelining最大的差別)吃溅。
當這些數(shù)據(jù)幀到達對端時溶诞,對端通過流標識符進行順序重組即可。
但是多路復用并沒有完全解決隊頭阻塞問題决侈,因為到達的消息仍然可能存在丟包的情況螺垢,比如服務端并行的發(fā)送給客戶端一波數(shù)據(jù)幀,但是在TCP層面第一個幀就傳輸丟失了赖歌,那么此時只能依賴TCP的重傳機制了枉圃。因此HTTP2.0多路復用只解決了HTTP層面的隊頭阻塞,TCP層面仍然會有俏站,除非TCP也做一次大的改革讯蒲,也利用HTTP2.0那樣,在每一個數(shù)據(jù)庫上打上流標識符肄扎。
1.3.3 Header壓縮
頭部壓縮依賴的是靜態(tài)表和動態(tài)表以及哈夫曼壓縮算法墨林。
即:Header 名稱通過靜態(tài)表與動態(tài)表的碼表表示,而Value則是通過哈夫曼算法進行壓縮犯祠。
因此大大減少了帶寬旭等。
具體見:https://datatracker.ietf.org/doc/html/rfc7540#page-14
1.3.4 服務端推送
這里的推送并不是我們常說的WebSocket、SSE協(xié)議哈衡载。
這里指搔耕,當前端向后端索要文件時,譬如JS文件,那么后端可以將JS弃榨、CSS菩收、圖片等信息都返回給客戶端,減少請求次數(shù)鲸睛。