
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最大的缺陷在于:原本客戶端的串型轉移到了服務器上??蛻舳瞬⑿邪l(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ù)。