偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

圖解 | 什么是HTTP簡(jiǎn)史

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
超文本傳輸協(xié)議是分布式協(xié)作超媒體信息系統(tǒng)的應(yīng)用協(xié)議。超文本傳輸協(xié)議是萬(wàn)維網(wǎng)數(shù)據(jù)通信的基礎(chǔ),在萬(wàn)維網(wǎng)中超文本文檔包括到用戶(hù)可以輕松訪(fǎng)問(wèn)的其他資源的超鏈接。

[[344212]]

本文轉(zhuǎn)載自微信公眾號(hào)「后端技術(shù)指南針」,作者后端技術(shù)指南針 。轉(zhuǎn)載本文請(qǐng)聯(lián)系后端技術(shù)指南針公眾號(hào)。

今天一起來(lái)研究Http協(xié)議的一些事情,通過(guò)本文你將了解到以下內(nèi)容:

  • Http協(xié)議各版本的對(duì)比和優(yōu)缺點(diǎn)
  • Http2.0協(xié)議相關(guān)的SPDY協(xié)議、二進(jìn)制分幀協(xié)議、多路復(fù)用、首部壓縮、服務(wù)推送等基本原理
  • HTTP3.0和QUIC協(xié)議

乘風(fēng)破浪前往知識(shí)的海洋吧,要開(kāi)船了!

1. Http協(xié)議各版本的對(duì)比

Http超文本傳輸協(xié)議同空氣一般,感觸不到它的存在但是又無(wú)處不在,筆者從維基百科摘錄了一些Http協(xié)議的發(fā)展歷程的簡(jiǎn)單信息,一起來(lái)看下吧:

超文本傳輸協(xié)議是分布式協(xié)作超媒體信息系統(tǒng)的應(yīng)用協(xié)議。超文本傳輸協(xié)議是萬(wàn)維網(wǎng)數(shù)據(jù)通信的基礎(chǔ),在萬(wàn)維網(wǎng)中超文本文檔包括到用戶(hù)可以輕松訪(fǎng)問(wèn)的其他資源的超鏈接。

蒂姆·伯納斯·李于1989年在歐洲核子研究中心發(fā)起了超文本傳輸協(xié)議的開(kāi)發(fā)。早期的超文本傳輸協(xié)議征求意見(jiàn)(RFCs)的開(kāi)發(fā)是由互聯(lián)網(wǎng)工程任務(wù)組(IETF)和萬(wàn)維網(wǎng)聯(lián)盟(W3C)共同努力的結(jié)果,其工作后來(lái)轉(zhuǎn)移到IETF。

萬(wàn)維網(wǎng)之父蒂姆·伯納斯·李簡(jiǎn)介

Tim Berners-Lee是英國(guó)工程師和計(jì)算機(jī)科學(xué)家,最著名的是萬(wàn)維網(wǎng)的發(fā)明者。他是牛津大學(xué)計(jì)算機(jī)科學(xué)教授和麻省理工學(xué)院教授。

他于1989年3月12日提出了一種信息管理系統(tǒng),然后在同年11月中旬通過(guò)Internet實(shí)現(xiàn)了超文本傳輸協(xié)議HTTP客戶(hù)端和服務(wù)器之間的首次成功通信。

他是萬(wàn)維網(wǎng)聯(lián)盟W3C的負(fù)責(zé)人,該聯(lián)盟負(fù)責(zé)監(jiān)督Web的持續(xù)發(fā)展,他還是萬(wàn)維網(wǎng)基金會(huì)的創(chuàng)始人,還是麻省理工學(xué)院計(jì)算機(jī)科學(xué)和人工智能實(shí)驗(yàn)室CSAIL的3Com創(chuàng)始人主席和高級(jí)研究員,他也是網(wǎng)絡(luò)科學(xué)研究計(jì)劃WSRI的主任和MIT集體智慧中心的顧問(wèn)委員會(huì)成員,他也是開(kāi)放數(shù)據(jù)研究所的創(chuàng)始人兼總裁,目前是社交網(wǎng)絡(luò)MeWe的顧問(wèn)。

2004年,伯納斯·李因其開(kāi)創(chuàng)性工作而被女王伊麗莎白二世封為爵士。在2009年4月,他當(dāng)選為美國(guó)國(guó)家科學(xué)院外籍研究員,位列《時(shí)代》雜志的20世紀(jì)100位最重要人物名單被譽(yù)為“萬(wàn)維網(wǎng)發(fā)明者”獲得了2016年圖靈獎(jiǎng)。

[[344213]]

 

http各個(gè)版本的基本情況

http協(xié)議經(jīng)過(guò)20多年的演進(jìn)出現(xiàn)過(guò)0.9、1.0、1.1、2.0、3.0五個(gè)主要版本,筆者畫(huà)了張圖看下:

 

A.Http0.9版本

0.9是鼻祖版本,它的主要特點(diǎn)包括:

  • 請(qǐng)求方法支持有限

只支持GET請(qǐng)求方式,不支持其他請(qǐng)求方式 因此客戶(hù)端向服務(wù)端傳輸信息的量非常有限,也就是現(xiàn)在常用的Post請(qǐng)求無(wú)法使用

  • 不支持請(qǐng)求頭header

不能在請(qǐng)求中指定版本號(hào),服務(wù)端只具有返回HTML字符串的能力

  • 響應(yīng)即關(guān)閉

服務(wù)端相響應(yīng)之后,立即關(guān)閉TCP連接

B.Http1.0版本

1.0版本主要是對(duì)0.9版本的強(qiáng)化,效果也比較明顯,主要特性和缺點(diǎn)包括:

  • 豐富請(qǐng)求方法

請(qǐng)求方式新增了POST,DELETE,PUT,HEADER等方式,提高了客戶(hù)端向服務(wù)端發(fā)送信息的量級(jí)

  • 增加請(qǐng)求頭和響應(yīng)頭

增添了請(qǐng)求頭和響應(yīng)頭的概念,可以在通信中指定了HTTP協(xié)議版本號(hào),以及其他header信息,使得C/S交互更加靈活方便

  • 豐富數(shù)據(jù)傳輸內(nèi)容

擴(kuò)充了傳輸內(nèi)容格式包括:圖片、音視頻資源、二進(jìn)制等都可以進(jìn)行傳輸,相比0.9的只能傳輸html內(nèi)容讓http的應(yīng)用場(chǎng)景更多

  • 鏈接復(fù)用性差

1.0版本中每個(gè)TCP連接只能發(fā)送一個(gè)請(qǐng)求,數(shù)據(jù)發(fā)送完畢連接就關(guān)閉,如果還要請(qǐng)求其他資源,就必須重新建立連接。TCP為了保證正確性和可靠性需要客戶(hù)端和服務(wù)器三次握手和四次揮手,因此建立連接成本很高,基于擁塞控制開(kāi)始時(shí)發(fā)送速率較慢,所以1.0版本的性能并不理想。

  • 無(wú)狀態(tài)無(wú)連接的弊端

1.0版本是無(wú)狀態(tài)且無(wú)連接的,換句話(huà)說(shuō)就是服務(wù)器不跟蹤不記錄請(qǐng)求過(guò)的狀態(tài),客戶(hù)端每次請(qǐng)求都需要建立tcp連接不能復(fù)用,并且1.0規(guī)定在前一個(gè)請(qǐng)求響應(yīng)到達(dá)之后下一個(gè)請(qǐng)求才能發(fā)送,如果前一個(gè)阻塞后面的請(qǐng)求就會(huì)被阻塞。 丟包和亂序問(wèn)題和高成本的鏈接過(guò)程讓復(fù)用和隊(duì)頭阻塞產(chǎn)生很多問(wèn)題,所以無(wú)連接無(wú)狀態(tài)是1.0版本的一個(gè)弱肋。

C.Http1.1版本

1.1版本在1.0版本發(fā)布后大約1年就推出了,是對(duì)1.0版本的優(yōu)化和完善,1.1版本的主要特點(diǎn)包括:

  • 增加長(zhǎng)連接

新增Connection字段,可以設(shè)置keep-alive值保持連接不斷開(kāi),即 TCP 連接默認(rèn)不關(guān)閉,可以被多個(gè)請(qǐng)求復(fù)用,這也是1.1版本很重要的優(yōu)化,但是在S端服務(wù)器只有處理完一個(gè)回應(yīng),才會(huì)進(jìn)行下一個(gè)回應(yīng)。要是前面的回應(yīng)特別慢,后面就會(huì)有許多請(qǐng)求排隊(duì)等著,仍然存在隊(duì)頭阻塞問(wèn)題。

  • 管道化

在長(zhǎng)連接的基礎(chǔ)上,管道化可以不等第一個(gè)請(qǐng)求響應(yīng)繼續(xù)發(fā)送后面的請(qǐng)求,但響應(yīng)的順序還是按照請(qǐng)求的順序返回,即在同一個(gè)TCP連接中,客戶(hù)端可以同時(shí)發(fā)送多個(gè)請(qǐng)求,進(jìn)一步改進(jìn)了HTTP協(xié)議的傳輸效率。

  • 更多的請(qǐng)求方法

增加了 PUT、PATCH、OPTIONS、DELETE 等請(qǐng)求方式。

  • host字段

Host字段用來(lái)指定服務(wù)器的域名,這樣就可以將多種請(qǐng)求發(fā)往同一臺(tái)服務(wù)器上的不同網(wǎng)站,提高了機(jī)器的復(fù)用,這個(gè)也是重要的優(yōu)化

D.Http2.0版本

2.0版本是個(gè)里程碑式的版本,相比1.x版本有了非常多的優(yōu)化去適應(yīng)當(dāng)前的網(wǎng)絡(luò)場(chǎng)景,其中幾個(gè)重要功能點(diǎn)包括:

  • 二進(jìn)制格式

1.x是文本協(xié)議,然而2.0是以二進(jìn)制幀為基本單位,可以說(shuō)是一個(gè)二進(jìn)制協(xié)議,將所有傳輸?shù)男畔⒎指顬橄⒑蛶?,并采用二進(jìn)制格式的編碼,一幀中包含數(shù)據(jù)和標(biāo)識(shí)符,使得網(wǎng)絡(luò)傳輸變得高效而靈活。

  • 多路復(fù)用

這是一個(gè)非常重要的改進(jìn),1.x中建立多個(gè)連接的消耗以及效率都存在問(wèn)題,2.0版本的多路復(fù)用多個(gè)請(qǐng)求共用一個(gè)連接,多個(gè)請(qǐng)求可以同時(shí)在一個(gè)TCP連接上并發(fā),主要借助于二進(jìn)制幀中的標(biāo)識(shí)進(jìn)行區(qū)分實(shí)現(xiàn)鏈路的復(fù)用。

  • 頭部壓縮

2.0版本使用使用HPACK算法對(duì)頭部header數(shù)據(jù)進(jìn)行壓縮,從而減少請(qǐng)求的大小提高效率,這個(gè)非常好理解,之前每次發(fā)送都要帶相同的header,顯得很冗余,2.0版本對(duì)頭部信息進(jìn)行增量更新有效減少了頭部數(shù)據(jù)的傳輸。

  • 服務(wù)端推送

這個(gè)功能有點(diǎn)意思,之前1.x版本服務(wù)端都是收到請(qǐng)求后被動(dòng)執(zhí)行,在2.0版本允許服務(wù)器主動(dòng)向客戶(hù)端發(fā)送資源,這樣在客戶(hù)端可以起到加速的作用。

2. Http2.0 詳解

前面對(duì)比了幾個(gè)版本的演進(jìn)和優(yōu)化過(guò)程,接下來(lái)深入研究下2.0版本的一些特性及其基本實(shí)現(xiàn)原理。

從對(duì)比來(lái)看2.0版本并不是在1.1版本上的一些優(yōu)化而是革新,因?yàn)?.0背負(fù)了更多的性能目標(biāo)任務(wù),1.1雖然增加了長(zhǎng)連接和管道化,但是從根本上并沒(méi)有實(shí)現(xiàn)真正的高性能。

2.0的設(shè)計(jì)目標(biāo)是在兼容1.x語(yǔ)義和操作的基礎(chǔ)上,給用戶(hù)帶來(lái)更快捷、更簡(jiǎn)單、更安全的體驗(yàn)高效地利用當(dāng)前的網(wǎng)絡(luò)帶寬,為此2.0做了很多調(diào)整主要包括:二進(jìn)制化分幀、多路復(fù)用、頭部壓縮等。

akamai做了http2.0和http1.1在加載過(guò)程中的對(duì)比效果(實(shí)驗(yàn)中加載379個(gè)小片段 在筆者的電腦上的加載時(shí)間是0.99s VS 5.80s):

 

https://http2.akamai.com/demo

2.1 SPDY協(xié)議

要說(shuō)2.0版本標(biāo)準(zhǔn)和新特性就必須提谷歌的SPDY協(xié)議,看一下百度百科:

SPDY是Google開(kāi)發(fā)的基于TCP的會(huì)話(huà)層協(xié)議,用以最小化網(wǎng)絡(luò)延遲,提升網(wǎng)絡(luò)速度,優(yōu)化用戶(hù)的網(wǎng)絡(luò)使用體驗(yàn)。SPDY并不是一種用于替代HTTP的協(xié)議,而是對(duì)HTTP協(xié)議的增強(qiáng)。

新協(xié)議的功能包括數(shù)據(jù)流的多路復(fù)用、請(qǐng)求優(yōu)先級(jí)以及HTTP報(bào)頭壓縮。谷歌表示引入SPDY協(xié)議后,在實(shí)驗(yàn)室測(cè)試中頁(yè)面加載速度比原先快64%。

隨后SPDY協(xié)議得到Chrome、Firefox等大型瀏覽器的支持,在一些大型網(wǎng)站和小型網(wǎng)站種部署,這個(gè)高效的協(xié)議引起了HTTP工作組的注意,在此基礎(chǔ)上制定了官方Http2.0標(biāo)準(zhǔn)。

之后幾年SPDY和Http2.0繼續(xù)演進(jìn)相互促進(jìn),Http2.0讓服務(wù)器、瀏覽器和網(wǎng)站開(kāi)發(fā)者在新協(xié)議中獲得更好的體驗(yàn),很快被大眾所認(rèn)可。

2.2 二進(jìn)制分幀層

二進(jìn)制分幀層binary framing layer在不修改請(qǐng)求方法和語(yǔ)義的基礎(chǔ)上,重新設(shè)計(jì)了編碼機(jī)制,如圖為http2.0分層結(jié)構(gòu)(圖片來(lái)自參考4):

 

二進(jìn)制編碼機(jī)制使得通信可以在單個(gè)TCP連接上進(jìn)行,該連接在整個(gè)對(duì)話(huà)期間一直處于活躍狀態(tài)。

二進(jìn)制協(xié)議將通信數(shù)據(jù)分解為更小的幀,數(shù)據(jù)幀充斥在C/S之間的雙向數(shù)據(jù)流中,就像雙向多車(chē)道的高速路,來(lái)往如織川流不息:

 

要理解二進(jìn)制分幀層需要知道四個(gè)概念:

鏈接Link

就是指一條C/S之間的TCP鏈接,這是個(gè)基礎(chǔ)的鏈路數(shù)據(jù)的高速公路

數(shù)據(jù)流Stream

已建立的TCP連接內(nèi)的雙向字節(jié)流,TCP鏈接中可以承載一條或多條消息

消息Message

消息屬于一個(gè)數(shù)據(jù)流,消息就是邏輯請(qǐng)求或響應(yīng)消息對(duì)應(yīng)的完整的一系列幀,也就是幀組成了消息

幀F(xiàn)rame

幀是通信的最小單位,每個(gè)幀都包含幀頭和消息體,標(biāo)識(shí)出當(dāng)前幀所屬的數(shù)據(jù)流

四者是一對(duì)多的包含關(guān)系,筆者畫(huà)了一張圖:

 

 

再來(lái)看一下HeadersFrame頭部幀的結(jié)構(gòu):

 

再來(lái)看一下HeadersFrame頭部幀的結(jié)構(gòu):從各個(gè)域可以看到長(zhǎng)度、類(lèi)型、標(biāo)志位、流標(biāo)識(shí)符、數(shù)據(jù)凈荷等,感興趣可以閱讀rfc7540相關(guān)文檔。

  1. https://httpwg.org/specs/rfc7540.html 

總之2.0版本將通信數(shù)據(jù)分解為二進(jìn)制編碼幀進(jìn)行交換,每個(gè)幀對(duì)應(yīng)著特定數(shù)據(jù)流中的特定消息,所有幀和流都在一個(gè)TCP連接內(nèi)復(fù)用,二進(jìn)制分幀協(xié)議是2.0其他功能和性能優(yōu)化的重要基礎(chǔ)。

 

2.3 多路復(fù)用

1.1版本中存在隊(duì)首阻塞問(wèn)題,因此如果客戶(hù)端要發(fā)起多個(gè)并行請(qǐng)求來(lái)提升性能,必須使用多個(gè)TCP連接,這樣就要承受更大延時(shí)和建鏈拆鏈成本,不能有效利用TCP鏈接。

由于2.0版本中使用新的二進(jìn)制分幀協(xié)議突破了1.0的諸多限制,從根本上實(shí)現(xiàn)了真正的請(qǐng)求和響應(yīng)多路復(fù)用。

客戶(hù)端和服務(wù)器將交互數(shù)據(jù)分解為相互獨(dú)立的幀,互不影響地交錯(cuò)傳輸,最后再在對(duì)端根據(jù)幀頭中的流標(biāo)識(shí)符把它們重新組裝起來(lái),從而實(shí)現(xiàn)了TCP鏈接的多路復(fù)用。

如圖展示了2.0版本的基于幀的消息通信過(guò)程(圖片來(lái)自參考4):

 


 

 

2.4 首部壓縮

A.Header冗余傳輸

我們都知道http請(qǐng)求都有header部分,每個(gè)包都有并且相對(duì)于一條鏈接而言大部分的包的header部分都是相同的,這樣的話(huà)每次傳輸相同的部分確實(shí)非常浪費(fèi)。

現(xiàn)代網(wǎng)絡(luò)中每個(gè)網(wǎng)頁(yè)平均包含100多個(gè)http請(qǐng)求,每個(gè)請(qǐng)求頭平均有300-500字節(jié),總數(shù)據(jù)量達(dá)到幾十KB以上,這樣可能造成數(shù)據(jù)延時(shí),尤其復(fù)雜的WiFi環(huán)境或者蜂窩網(wǎng)絡(luò),這樣只能看到手機(jī)在轉(zhuǎn)圈,但是這些請(qǐng)求頭之間通常幾乎沒(méi)有變化,在本已經(jīng)擁擠的鏈路中多次傳輸相同的數(shù)據(jù)部分確實(shí)不是高效做法。

基于TCP設(shè)計(jì)的擁塞控制具有線(xiàn)增積減AIMD特性,如果發(fā)生丟包那么傳輸速率將大幅度下降,這樣在擁擠的網(wǎng)絡(luò)環(huán)境中大的包頭意味著只能加劇擁塞控制造成的低速率傳輸。

B.Http壓縮和犯罪攻擊

在2.0版本的HPACK算法之前,http壓縮使用gzip去壓縮,后來(lái)提出的SPDY算法對(duì)Headers進(jìn)行特殊設(shè)計(jì),但是它依舊使用的是DEFLATE算法。

在后面的一些實(shí)際應(yīng)用中發(fā)現(xiàn)DEFLATE和SPDY都有被攻擊的危險(xiǎn),因?yàn)镈EFLATE算法使用后向字符串匹配和動(dòng)態(tài)Huffman編碼,攻擊者可以控制部分請(qǐng)求頭部通過(guò)修改請(qǐng)求部分然后看壓縮之后大小改變多少,如果變小了攻擊者就知道注入的文本和請(qǐng)求中的某些內(nèi)容有重復(fù)。

這個(gè)過(guò)程有點(diǎn)像俄羅斯方塊的消除過(guò)程,這樣經(jīng)過(guò)一段時(shí)間的嘗試數(shù)據(jù)內(nèi)容就可能被全部搞清楚,由于這種風(fēng)險(xiǎn)的存在才研發(fā)出更安全的壓縮算法。

C.HPACK算法

2.0版本中HPACK算法在C/S中使用首部表來(lái)存儲(chǔ)之前發(fā)送的鍵值對(duì),對(duì)于相同的數(shù)據(jù)通信期間幾乎不會(huì)改變的通用鍵值對(duì)只需發(fā)送一次即可。

極端情況如果請(qǐng)求頭每次沒(méi)有變化,那么傳輸中則不包含首部,也就是首部開(kāi)銷(xiāo)就是零字節(jié)。如果首部鍵值對(duì)發(fā)生變化了,也只需要發(fā)送變化的數(shù)據(jù),并且將新增或修改的首部幀會(huì)被追加到首部表,首部表在鏈接存活期始終存在, 并且由客戶(hù)端和服務(wù)器共同更新和維護(hù)。

簡(jiǎn)單說(shuō)就是客戶(hù)端和服務(wù)端共同維護(hù)了一個(gè)key-value的結(jié)構(gòu),發(fā)生變化時(shí)則更新傳輸,否則就不傳輸,這樣相當(dāng)于首次全量傳輸之后增量更新傳輸即可,這個(gè)思想在日常開(kāi)發(fā)中也非常普遍,不用想的太復(fù)雜。

如圖展示了首部表的更新過(guò)程(圖片來(lái)自參考4):

 

hpack算法的相關(guān)文檔:

https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12

2.5 服務(wù)端推送

服務(wù)端推送是2.0版本新增的一個(gè)強(qiáng)大功能,和一般的一問(wèn)一答式的C/S交互不同,推送式交互中服務(wù)器可以對(duì)客戶(hù)端的一個(gè)請(qǐng)求發(fā)送多個(gè)響應(yīng),除了對(duì)最初請(qǐng)求的響應(yīng)外還向客戶(hù)端推送額外資源,無(wú)需客戶(hù)端明確地請(qǐng)求也可以推送。

舉個(gè)栗子:

想象一下你去餐廳吃飯,服務(wù)好的快餐廳在你點(diǎn)好一份牛肉面之后,還會(huì)給你送上餐巾紙、筷子、勺子甚至調(diào)料等,這樣主動(dòng)式的服務(wù),節(jié)約了客人的時(shí)間并且提高了用餐體驗(yàn)。

在實(shí)際的C/S交互中這種主動(dòng)推送額外資源的方法很有效,因?yàn)閹缀趺總€(gè)網(wǎng)絡(luò)應(yīng)用都會(huì)包含多種資源,客戶(hù)端需要全部逐個(gè)獲取它們,此時(shí)如果讓服務(wù)器提前推送這些資源,從而可以有效減少額外的延遲時(shí)間,因?yàn)榉?wù)器可以知道客戶(hù)端下一步要請(qǐng)求什么資源。

如圖為服務(wù)端推送的簡(jiǎn)單過(guò)程(圖片來(lái)自參考4):

 

 

 

 

3.HTTP2.0和HTTP3.0

科技永不止步。

我們都知道互聯(lián)網(wǎng)中業(yè)務(wù)是不斷迭代前進(jìn)的,像HTTP這種重要的網(wǎng)絡(luò)協(xié)議也是如此,新版本是對(duì)舊版本的揚(yáng)棄。

3.1 HTTP2.0和TCP的愛(ài)恨糾葛

HTTP2.0是2015年推出的,還是比較年輕的,其重要的二進(jìn)制分幀協(xié)議、多路復(fù)用、頭部壓縮、服務(wù)端推送等重要優(yōu)化使HTTP協(xié)議真正上了一個(gè)新臺(tái)階。

 

像谷歌這種重要的公司并沒(méi)有滿(mǎn)足于此,而且想繼續(xù)提升HTTP的性能,花最少的時(shí)間和資源獲取極致體驗(yàn)。

那么肯定要問(wèn)HTTP2.0雖然性能已經(jīng)不錯(cuò)了,還有什么不足嗎?

  • 建立連接時(shí)間長(zhǎng)(本質(zhì)上是TCP的問(wèn)題)
  • 隊(duì)頭阻塞問(wèn)題
  • 移動(dòng)互聯(lián)網(wǎng)領(lǐng)域表現(xiàn)不佳(弱網(wǎng)環(huán)境)
  • ......

熟悉HTTP2.0協(xié)議的同學(xué)應(yīng)該知道,這些缺點(diǎn)基本都是由于TCP協(xié)議引起的,水能載舟亦能覆舟,其實(shí)TCP也很無(wú)辜呀!

 

在我們眼里,TCP是面向連接、可靠的傳輸層協(xié)議,當(dāng)前幾乎所有重要的協(xié)議和應(yīng)用都是基于TCP來(lái)實(shí)現(xiàn)的。

網(wǎng)絡(luò)環(huán)境的改變速度很快,但是TCP協(xié)議相對(duì)緩慢,正是這種矛盾促使谷歌做出了一個(gè)看似出乎意料的決定-基于UDP來(lái)開(kāi)發(fā)新一代HTTP協(xié)議。

3.2 谷歌為什么選擇UDP

上文提到,谷歌選擇UDP是看似出乎意料的,仔細(xì)想一想其實(shí)很有道理。

我們單純地看看TCP協(xié)議的不足和UDP的一些優(yōu)點(diǎn):

  • 基于TCP開(kāi)發(fā)的設(shè)備和協(xié)議非常多,兼容困難
  • TCP協(xié)議棧是Linux內(nèi)部的重要部分,修改和升級(jí)成本很大
  • UDP本身是無(wú)連接的、沒(méi)有建鏈和拆鏈成本
  • UDP的數(shù)據(jù)包無(wú)隊(duì)頭阻塞問(wèn)題
  • UDP改造成本小

從上面的對(duì)比可以知道,谷歌要想從TCP上進(jìn)行改造升級(jí)絕非易事,但是UDP雖然沒(méi)有TCP為了保證可靠連接而引發(fā)的問(wèn)題,但是UDP本身不可靠,又不能直接用。

 

綜合而知,谷歌決定在UDP基礎(chǔ)上改造一個(gè)具備TCP協(xié)議優(yōu)點(diǎn)的新協(xié)議也就順理成章了,這個(gè)新協(xié)議就是QUIC協(xié)議。

3.3 QUIC協(xié)議和HTTP3.0

QUIC其實(shí)是Quick UDP Internet Connections的縮寫(xiě),直譯為快速UDP互聯(lián)網(wǎng)連接。

 

我們來(lái)看看維基百科對(duì)于QUIC協(xié)議的一些介紹:

QUIC協(xié)議最初由Google的Jim Roskind設(shè)計(jì),實(shí)施并于2012年部署,在2013年隨著實(shí)驗(yàn)的擴(kuò)大而公開(kāi)宣布,并向IETF進(jìn)行了描述。

QUIC提高了當(dāng)前正在使用TCP的面向連接的Web應(yīng)用程序的性能。它在兩個(gè)端點(diǎn)之間使用用戶(hù)數(shù)據(jù)報(bào)協(xié)議(UDP)建立多個(gè)復(fù)用連接來(lái)實(shí)現(xiàn)此目的。

QUIC的次要目標(biāo)包括減少連接和傳輸延遲,在每個(gè)方向進(jìn)行帶寬估計(jì)以避免擁塞。它還將擁塞控制算法移動(dòng)到用戶(hù)空間,而不是內(nèi)核空間,此外使用前向糾錯(cuò)(FEC)進(jìn)行擴(kuò)展,以在出現(xiàn)錯(cuò)誤時(shí)進(jìn)一步提高性能。

HTTP3.0又稱(chēng)為HTTP Over QUIC,其棄用TCP協(xié)議,改為使用基于UDP協(xié)議的QUIC協(xié)議來(lái)實(shí)現(xiàn)。

 

4. QUIC協(xié)議詳解

擇其善者而從之,其不善者而改之。

HTTP3.0既然選擇了QUIC協(xié)議,也就意味著HTTP3.0基本繼承了HTTP2.0的強(qiáng)大功能,并且進(jìn)一步解決了HTTP2.0存在的一些問(wèn)題,同時(shí)必然引入了新的問(wèn)題。

 

QUIC協(xié)議必須要實(shí)現(xiàn)HTTP2.0在TCP協(xié)議上的重要功能,同時(shí)解決遺留問(wèn)題,我們來(lái)看看QUIC是如何實(shí)現(xiàn)的。

4.1 隊(duì)頭阻塞問(wèn)題

隊(duì)頭阻塞 Head-of-line blocking(縮寫(xiě)為HOL blocking)是計(jì)算機(jī)網(wǎng)絡(luò)中是一種性能受限的現(xiàn)象,通俗來(lái)說(shuō)就是:一個(gè)數(shù)據(jù)包影響了一堆數(shù)據(jù)包,它不來(lái)大家都走不了。

隊(duì)頭阻塞問(wèn)題可能存在于HTTP層和TCP層,在HTTP1.x時(shí)兩個(gè)層次都存在該問(wèn)題。

 

HTTP2.0協(xié)議的多路復(fù)用機(jī)制解決了HTTP層的隊(duì)頭阻塞問(wèn)題,但是在TCP層仍然存在隊(duì)頭阻塞問(wèn)題。

TCP協(xié)議在收到數(shù)據(jù)包之后,這部分?jǐn)?shù)據(jù)可能是亂序到達(dá)的,但是TCP必須將所有數(shù)據(jù)收集排序整合后給上層使用,如果其中某個(gè)包丟失了,就必須等待重傳,從而出現(xiàn)某個(gè)丟包數(shù)據(jù)阻塞整個(gè)連接的數(shù)據(jù)使用。

QUIC協(xié)議是基于UDP協(xié)議實(shí)現(xiàn)的,在一條鏈接上可以有多個(gè)流,流與流之間是互不影響的,當(dāng)一個(gè)流出現(xiàn)丟包影響范圍非常小,從而解決隊(duì)頭阻塞問(wèn)題。

4.2 0RTT 建鏈

衡量網(wǎng)絡(luò)建鏈的常用指標(biāo)是RTT Round-Trip Time,也就是數(shù)據(jù)包一來(lái)一回的時(shí)間消耗。

 

RTT包括三部分:往返傳播時(shí)延、網(wǎng)絡(luò)設(shè)備內(nèi)排隊(duì)時(shí)延、應(yīng)用程序數(shù)據(jù)處理時(shí)延。

 

一般來(lái)說(shuō)HTTPS協(xié)議要建立完整鏈接包括:TCP握手和TLS握手,總計(jì)需要至少2-3個(gè)RTT,普通的HTTP協(xié)議也需要至少1個(gè)RTT才可以完成握手。

然而,QUIC協(xié)議可以實(shí)現(xiàn)在第一個(gè)包就可以包含有效的應(yīng)用數(shù)據(jù),從而實(shí)現(xiàn)0RTT,但這也是有條件的。

 

簡(jiǎn)單來(lái)說(shuō),基于TCP協(xié)議和TLS協(xié)議的HTTP2.0在真正發(fā)送數(shù)據(jù)包之前需要花費(fèi)一些時(shí)間來(lái)完成握手和加密協(xié)商,完成之后才可以真正傳輸業(yè)務(wù)數(shù)據(jù)。

但是QUIC則第一個(gè)數(shù)據(jù)包就可以發(fā)業(yè)務(wù)數(shù)據(jù),從而在連接延時(shí)有很大優(yōu)勢(shì),可以節(jié)約數(shù)百毫秒的時(shí)間。

 

QUIC的0RTT也是需要條件的,對(duì)于第一次交互的客戶(hù)端和服務(wù)端0RTT也是做不到的,畢竟雙方完全陌生。

因此,QUIC協(xié)議可以分為首次連接和非首次連接,兩種情況進(jìn)行討論。

4.3 首次連接和非首次連接

使用QUIC協(xié)議的客戶(hù)端和服務(wù)端要使用1RTT進(jìn)行密鑰交換,使用的交換算法是DH(Diffie-Hellman)迪菲-赫爾曼算法。

DH算法開(kāi)辟了密鑰交換的新思路,在之前的文章中提到的RSA算法也是基于這種思想實(shí)現(xiàn)的,但是DH算法和RSA的密鑰交換不完全一樣,感興趣的讀者可以看看DH算法的數(shù)學(xué)原理。

DH算法開(kāi)辟了密鑰交換的新思路,在之前的文章中提到的RSA算法也是基于這種思想實(shí)現(xiàn)的,但是DH算法和RSA的密鑰交換不完全一樣,感興趣的讀者可以看看DH算法的數(shù)學(xué)原理。

4.3.1 首次連接

簡(jiǎn)單來(lái)說(shuō)一下,首次連接時(shí)客戶(hù)端和服務(wù)端的密鑰協(xié)商和數(shù)據(jù)傳輸過(guò)程,其中涉及了DH算法的基本過(guò)程:

 

4.3.2 非首次連接

前面提到客戶(hù)端和服務(wù)端首次連接時(shí)服務(wù)端傳遞了config包,里面包含了服務(wù)端公鑰和兩個(gè)隨機(jī)數(shù),客戶(hù)端會(huì)將config存儲(chǔ)下來(lái),后續(xù)再連接時(shí)可以直接使用,從而跳過(guò)這個(gè)1RTT,實(shí)現(xiàn)0RTT的業(yè)務(wù)數(shù)據(jù)交互。

客戶(hù)端保存config是有時(shí)間期限的,在config失效之后仍然需要進(jìn)行首次連接時(shí)的密鑰交換。

4.4 前向安全問(wèn)題

前向安全是密碼學(xué)領(lǐng)域的專(zhuān)業(yè)術(shù)語(yǔ),看下百度上的解釋?zhuān)?/p>

前向安全或前向保密Forward Secrecy是密碼學(xué)中通訊協(xié)議的安全屬性,指的是長(zhǎng)期使用的主密鑰泄漏不會(huì)導(dǎo)致過(guò)去的會(huì)話(huà)密鑰泄漏。

前向安全能夠保護(hù)過(guò)去進(jìn)行的通訊不受密碼或密鑰在未來(lái)暴露的威脅,如果系統(tǒng)具有前向安全性,就可以保證在主密鑰泄露時(shí)歷史通訊的安全,即使系統(tǒng)遭到主動(dòng)攻擊也是如此。

通俗來(lái)說(shuō),前向安全指的是密鑰泄漏也不會(huì)讓之前加密的數(shù)據(jù)被泄漏,影響的只有當(dāng)前,對(duì)之前的數(shù)據(jù)無(wú)影響。

前面提到QUIC協(xié)議首次連接時(shí)先后生成了兩個(gè)加密密鑰,由于config被客戶(hù)端存儲(chǔ)了,如果期間服務(wù)端私鑰泄漏,那么可以根據(jù)K = mod p計(jì)算出密鑰K。

如果一直使用這個(gè)密鑰進(jìn)行加解密,那么就可以用K解密所有歷史消息,因此后續(xù)又生成了新密鑰,使用其進(jìn)行加解密,當(dāng)時(shí)完成交互時(shí)則銷(xiāo)毀,從而實(shí)現(xiàn)了前向安全。

 

4.5 前向糾錯(cuò)

前向糾錯(cuò)是通信領(lǐng)域的術(shù)語(yǔ),看下百科的解釋?zhuān)?/p>

前向糾錯(cuò)也叫前向糾錯(cuò)碼Forward Error Correction 簡(jiǎn)稱(chēng)FEC 是增加數(shù)據(jù)通訊可信度的方法,在單向通訊信道中,一旦錯(cuò)誤被發(fā)現(xiàn),其接收器將無(wú)權(quán)再請(qǐng)求傳輸。

FEC 是利用數(shù)據(jù)進(jìn)行傳輸冗余信息的方法,當(dāng)傳輸中出現(xiàn)錯(cuò)誤,將允許接收器再建數(shù)據(jù)。

聽(tīng)這段描述就是做校驗(yàn)的,看看QUIC協(xié)議是如何實(shí)現(xiàn)的:

QUIC每發(fā)送一組數(shù)據(jù)就對(duì)這組數(shù)據(jù)進(jìn)行異或運(yùn)算,并將結(jié)果作為一個(gè)FEC包發(fā)送出去,接收方收到這一組數(shù)據(jù)后根據(jù)數(shù)據(jù)包和FEC包即可進(jìn)行校驗(yàn)和糾錯(cuò)。

4.6 連接遷移

網(wǎng)絡(luò)切換幾乎無(wú)時(shí)無(wú)刻不在發(fā)生。

TCP協(xié)議使用五元組來(lái)表示一條唯一的連接,當(dāng)我們從4G環(huán)境切換到wifi環(huán)境時(shí),手機(jī)的IP地址就會(huì)發(fā)生變化,這時(shí)必須創(chuàng)建新的TCP連接才能繼續(xù)傳輸數(shù)據(jù)。

QUIC協(xié)議基于UDP實(shí)現(xiàn)摒棄了五元組的概念,使用64位的隨機(jī)數(shù)作為連接的ID,并使用該ID表示連接。

基于QUIC協(xié)議之下,我們?cè)谌粘ifi和4G切換時(shí),或者不同基站之間切換都不會(huì)重連,從而提高業(yè)務(wù)層的體驗(yàn)。

 

5. QUIC的應(yīng)用和前景

通過(guò)前面的一些介紹我們看出來(lái)QUIC協(xié)議雖然是基于UDP來(lái)實(shí)現(xiàn)的,但是它將TCP的重要功能都進(jìn)行了實(shí)現(xiàn)和優(yōu)化,否則使用者是不會(huì)買(mǎi)賬的。

QUIC協(xié)議的核心思想是將TCP協(xié)議在內(nèi)核實(shí)現(xiàn)的諸如可靠傳輸、流量控制、擁塞控制等功能轉(zhuǎn)移到用戶(hù)態(tài)來(lái)實(shí)現(xiàn),同時(shí)在加密傳輸方向的嘗試也推動(dòng)了TLS1.3的發(fā)展。

但是TCP協(xié)議的勢(shì)力過(guò)于強(qiáng)大,很多網(wǎng)絡(luò)設(shè)備甚至對(duì)于UDP數(shù)據(jù)包做了很多不友好的策略,進(jìn)行攔截從而導(dǎo)致成功連接率下降。

主導(dǎo)者谷歌在自家產(chǎn)品做了很多嘗試,國(guó)內(nèi)騰訊公司也做了很多關(guān)于QUIC協(xié)議的嘗試。

其中騰訊云對(duì)QUIC協(xié)議表現(xiàn)了很大的興趣,并做了一些優(yōu)化然后在一些重點(diǎn)產(chǎn)品中對(duì)連接遷移、QUIC成功率、弱網(wǎng)環(huán)境耗時(shí)等進(jìn)行了實(shí)驗(yàn),給出了來(lái)自生產(chǎn)環(huán)境的諸多寶貴數(shù)據(jù)。

簡(jiǎn)單看一組騰訊云在移動(dòng)互聯(lián)網(wǎng)場(chǎng)景下的不同丟包率下的請(qǐng)求耗時(shí)分布:

 

任何新生事物的推動(dòng)都是需要時(shí)間的,出現(xiàn)多年的HTTP2.0和HTTPS協(xié)議的普及度都沒(méi)有預(yù)想高,IPv6也是如此,不過(guò)QUIC已經(jīng)展現(xiàn)了強(qiáng)大的生命力,讓我們拭目以待吧!

6.本文小結(jié)

本文通過(guò)介紹Http協(xié)議的歷史演進(jìn)、各個(gè)版本的主要特征和優(yōu)缺點(diǎn)、重點(diǎn)介紹了Http2.0協(xié)議的一些特性,包括:SPDY協(xié)議、二進(jìn)制分幀協(xié)議、多路復(fù)用、首部壓縮、服務(wù)端推送等重要功能,篇幅有限不能展開(kāi)太多。

雖然http2.0版本協(xié)議有很多非常優(yōu)秀的功能并且在2015年正式發(fā)布,現(xiàn)在國(guó)內(nèi)外一些大廠基本都有使用http2.0承擔(dān)部分請(qǐng)求,但是目前仍然未廣泛普及。

目前http3.0版本在2018年也推出來(lái)了,至于http2.0和http3.0的推廣和普及是需要時(shí)間的,但是堅(jiān)信我們的網(wǎng)絡(luò)可以更安全、更快捷、更節(jié)約。

不過(guò)現(xiàn)在看看QUIC協(xié)議:基于UDP主體將TCP的重要功能轉(zhuǎn)移到用戶(hù)空間來(lái)實(shí)現(xiàn),從而繞開(kāi)內(nèi)核實(shí)現(xiàn)用戶(hù)態(tài)的TCP協(xié)議,但是真正實(shí)現(xiàn)起來(lái)還是非常復(fù)雜的。

 

網(wǎng)絡(luò)協(xié)議本身就很復(fù)雜,本文只能從整體出發(fā)對(duì)重要的部分做粗淺的闡述,如果對(duì)某個(gè)點(diǎn)很感興趣,可以查閱相關(guān)代碼和RFC文檔。

 

責(zé)任編輯:武曉燕 來(lái)源: 后端技術(shù)指南針
相關(guān)推薦

2021-09-01 09:52:52

路由器計(jì)算機(jī)架構(gòu)

2020-12-04 09:30:18

HTTPWeb前端

2021-02-14 19:51:04

車(chē)聯(lián)網(wǎng)5G4G

2020-08-31 06:41:52

RSA算法

2020-09-12 13:55:03

HTTP3.0UDP協(xié)議

2018-07-12 15:30:03

HTTP緩存機(jī)制

2020-09-21 06:53:41

NoSQL高并發(fā)面試

2020-08-31 07:43:58

二叉堆大頂堆存儲(chǔ)

2020-07-06 07:36:13

缺頁(yè)錯(cuò)誤

2020-07-27 07:55:51

條件概率

2021-06-02 10:52:01

HTTP3Linux

2021-08-03 09:33:55

HTTP網(wǎng)絡(luò)協(xié)議TCP

2021-08-03 10:10:16

HTTP連接管理

2015-10-09 15:07:02

HTTP網(wǎng)絡(luò)協(xié)議

2020-09-10 07:04:30

JSJavaScript 原型鏈

2022-07-10 21:33:31

DNS存儲(chǔ)公網(wǎng)

2021-05-12 08:20:53

開(kāi)發(fā)

2022-07-10 20:48:36

DHCP互聯(lián)網(wǎng)網(wǎng)絡(luò)

2018-10-09 09:28:12

HTTPHTTP協(xié)作服務(wù)器

2013-02-20 09:33:07

PythonWeb
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)