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


























