每一代HTTP協(xié)議都解決了什么問題?
最近簡單研究了HTTP協(xié)議的發(fā)展歷程,對此進行了一些總結(jié)。
讓我們逐一回顧一下HTTP的版本演進:HTTP/1.0 -> HTTP/1.1 -> HTTP/2.0 -> HTTP/3.0(QUIC)。
HTTP/1.0
HTTP 1.0于1996年首次發(fā)布,規(guī)定了瀏覽器與服務(wù)器之間只保持短暫的連接。每次瀏覽器請求都需要與服務(wù)器建立一個TCP連接,而在服務(wù)器完成請求處理后立即斷開TCP連接。然而,這種方式存在缺陷,因為TCP連接的建立需要經(jīng)歷三次握手,導(dǎo)致每次HTTP請求都要重新執(zhí)行這個繁瑣的過程,效率相當(dāng)?shù)拖隆?/p>
HTTP/1.1
HTTP 1.1于1997年發(fā)布,引入了默認(rèn)的持久連接(Connection: keep-alive),消除了每次HTTP請求都重新建立TCP連接的需求。盡管如此,它并未解決HOL(隊頭)阻塞問題。HOL阻塞指的是當(dāng)瀏覽器允許的并行請求數(shù)用完時,后續(xù)請求需要等待前面的請求完成。
HTTP/2.0
HTTP 2.0在2015年發(fā)布,通過引入多路復(fù)用解決了HOL阻塞問題。這一版本將一個TCP連接劃分為多個流(Stream),每個流中可以傳輸多個消息(Message),而每個消息則由多個最小的二進制幀(Frame)組成。通過為每個用戶操作分配一個流編號(Stream ID),建立了與服務(wù)端之間的TCP通道。這種方式使得客戶端的每個請求都可以開始下一次請求,從而解決了應(yīng)用層的隊頭阻塞。
不過,盡管HTTP/2.0解決了應(yīng)用層的隊頭阻塞問題,傳輸層(TCP)仍然存在隊頭阻塞。由于TCP協(xié)議的可靠性,即按順序發(fā)送和接收數(shù)據(jù),且受到擁塞控制的影響,少量的丟包可能導(dǎo)致整個TCP連接上的所有流被阻塞。
HTTP/3.0
HTTP 3.0的第一個草案于2020年發(fā)布,并于2022年6月6日正式成為RFC9114標(biāo)準(zhǔn)。HTTP/3.0摒棄了TCP,采用UDP上的QUIC協(xié)議來傳輸應(yīng)用層數(shù)據(jù),從而消除了傳輸層的隊頭阻塞問題。
QUIC使用UDP協(xié)議在兩個端點之間建立多個獨立的流(Stream),這意味著在大多數(shù)情況下,一個流的數(shù)據(jù)包丟失不會對其他流產(chǎn)生影響。這一創(chuàng)新有效地解決了隊頭阻塞問題,使得HTTP/3.0在性能和效率方面邁出了一大步。
HTTP 3.0 還沒有大面積的使用,我能想到的問題只有兩個。
第一個是 CN 地區(qū)對 UDP 的 QOS 或阻斷,尚不清楚后續(xù)是否會放寬。
第二個是UDP協(xié)議依賴四元組信息,大部分沒有公網(wǎng)IPv4的設(shè)備都需要經(jīng)過路由器或防火墻的NAT轉(zhuǎn)換才能和服務(wù)端進行通信。NAT 設(shè)備無法知道 UDP 連接什么時候斷開,因此在刪除自身的 NAT記錄時可能會導(dǎo)致尚在通信中的 UDP 連接斷開。
后面同事和我講了 QUIC 協(xié)議有一個 ConnectionId 之類的東西,就算網(wǎng)絡(luò)環(huán)境飄了,他都可以把連接恢復(fù)起來。
我查了一下,專業(yè)術(shù)語是:Connection Migration,有一個提案:https://datatracker.ietf.org/doc/html/draft-ietf-quic-transport-23#section-9 。
最后附上其他大佬畫的一張圖。
圖片
參考
? https://github.com/ByteByteGoHq/system-design-101