遲到的HTTP2簡明教程

The standardization effort was supported by Chrome, Opera, Firefox,[9] Internet Explorer 11, Safari, Amazon Silk, and Edge browsers.[10] Most major browsers had added HTTP/2 support by the end of 2015.[11] According to W3Techs, as of November 2017, 20.5% of the top 10 million websites supported HTTP/2.

這是一段來自維基百科的關(guān)于HTTP2的說明帮非,截止2015年底,主流瀏覽器都已經(jīng)對HTTP2做了支持兑宇,根據(jù)2017年11月的W3Techs報(bào)告說明启上,全球有1/5的大型網(wǎng)站都已經(jīng)使用了HTTP2了邢隧。作為碼農(nóng)的你已經(jīng)可以預(yù)料HTTP2的時(shí)代即將到來,對于HTTP2的技術(shù)細(xì)節(jié)你都準(zhǔn)備好了么冈在?

HTTP2的設(shè)計(jì)要點(diǎn)

Header壓縮

Server Push

Pipelining & Mulplexing

我們平常聽到的GZIP壓縮僅僅是針對HTTP請求的Body部分進(jìn)行的倒慧,這只能算是半壓縮。對于很多API服務(wù)來說,返回的內(nèi)容體其實(shí)并不大纫谅,這個(gè)時(shí)候請求頭就占據(jù)了大部分流量炫贤。HTTP2將魔爪伸到了HTTP頭部,這回是徹底的對整個(gè)請求都進(jìn)行壓縮了付秕。

HTTP2的頭壓縮原理完全不同于HTTP1.1兰珍,它將常用的HEADER鍵值對映射到一個(gè)靜態(tài)表里面的索引值,于是很多頭部的鍵值對使用一個(gè)位置索引來表示就可以了询吴。這樣便大大節(jié)省了頭部消息的長度掠河。對于那些不常用的自定義的頭部會使用一個(gè)動態(tài)表來維護(hù),具體原理有一定復(fù)雜度猛计,這里就不再啰嗦了唠摹。

Server Push不同于Websocket,Server Push一般是指服務(wù)器主動向客戶端推送數(shù)據(jù)有滑,這是一種單向的主動推送跃闹,而WebSocket是雙向的,這兩種技術(shù)不是競爭關(guān)系毛好。Server Push可以用在服務(wù)器主動向客戶端推送靜態(tài)資源,比如瀏覽器請求index.html時(shí)苛秕,服務(wù)器除了返回網(wǎng)頁內(nèi)容外肌访,還會將index.html頁面里面的各種css和js一起推送到瀏覽器緩存起來,當(dāng)瀏覽器分析了網(wǎng)頁內(nèi)容發(fā)現(xiàn)靜態(tài)資源時(shí)艇劫,不需要再去服務(wù)器請求一次吼驶,它只需要從緩存里直接拿就可以了。不過現(xiàn)代的網(wǎng)站的靜態(tài)資源大多都是CDN架構(gòu)的店煞,靜態(tài)資源都在第三方服務(wù)器蟹演,Server Push在這方面作用并不大。Server Push還可以用在推送通知消息顷蟀,比如誰關(guān)注了你酒请,誰給你點(diǎn)了贊等,這個(gè)可以替代古老的Comet技術(shù)和近幾年Google推廣的SPDY協(xié)議鸣个,它需要服務(wù)器維持當(dāng)前的TCP通道不關(guān)閉羞反,需要持續(xù)占用服務(wù)器資源。

Pipeline是指后一個(gè)HTTP請求無需等待前一個(gè)HTTP請求返回結(jié)果就可以提前發(fā)起囤萤。HTTP1.1也有Pipeline支持昼窗,但是有所不足,并行的還不夠徹底涛舍。它可以提前發(fā)起請求澄惊,但是卻限定了返回結(jié)果必須和收到請求的順序保持一致而不能亂序。如果第一個(gè)請求服務(wù)器處理慢了,那么后續(xù)的返回結(jié)果客戶端無法立即收到掸驱,而必須等到第一個(gè)結(jié)果全部返回了才行窘哈。HTTP2則解決了這個(gè)問題,它支持亂序返回亭敢,甚至不同請求的返回結(jié)果的分塊【HTTP Chunk】也可以交叉返回而不會混亂滚婉,這種技術(shù)稱之為Multiplexing【多路復(fù)用】。

HTTP2底層協(xié)議

HTTP2協(xié)議是二進(jìn)制協(xié)議帅刀,不同于HTTP1.1的文本協(xié)議让腹。文本協(xié)議是以特殊的符號結(jié)尾【換行回車符】來分割消息的,而二進(jìn)制協(xié)議是通過字節(jié)長度來分割消息扣溺。二進(jìn)制協(xié)議雖然直觀性不如文本協(xié)議骇窍,但是在實(shí)現(xiàn)的時(shí)候要簡單直接一些。

HTTP2為支持多路復(fù)用锥余,在同一條TCP通道上支持發(fā)送多個(gè)資源/請求腹纳,將每條資源/請求定義為一個(gè)Stream【流】,同一個(gè)TCP通道可以傳輸多個(gè)Stream驱犹。同時(shí)為了支持多個(gè)資源的并行交錯(cuò)發(fā)送嘲恍,將Stream再次分割為多個(gè)Frame【幀】,幀與幀之間可以交錯(cuò)發(fā)送雄驹。接收端通過流ID將這些幀組裝起來佃牛,通一個(gè)流ID的幀屬于同一個(gè)資源/請求。因?yàn)門CP協(xié)議已經(jīng)可以保證消息包是有序的医舆,所以接收端不必?fù)?dān)心亂序問題俘侠。

HTTP2的幀格式非常簡單,就是長度+類型+標(biāo)志位+流ID+PayLoad蔬将,長度就是PayLoad的字節(jié)數(shù)爷速,類型為一個(gè)字節(jié),標(biāo)志位為1個(gè)字節(jié)霞怀,流ID為4個(gè)字節(jié)惫东,剩下的長度就是PayLoad。不同類型的幀PayLoad不一樣里烦,標(biāo)志位也不一樣凿蒜。

HTTP2標(biāo)準(zhǔn)里定義了10種類型的幀。

HEADERS幀 頭信息胁黑,對應(yīng)于HTTP HEADER

DATA幀 對應(yīng)于HTTP Response Body

PRIORITY幀 用于調(diào)整流的優(yōu)先級

RST_STREAM幀 流終止幀废封,用于中斷資源的傳輸

SETTINGS幀 用戶客戶服務(wù)器交流連接配置信息

PUSH_PROMISE幀 服務(wù)器向客戶端主動推送資源

GOAWAY幀 通知對方斷開連接

PING幀 心跳幀,檢測往返時(shí)間和連接可用性

WINDOW_UPDATE幀 調(diào)整幀大小

CONTINUATION幀 HEADERS太大時(shí)的續(xù)幀

HTTP2標(biāo)準(zhǔn)定義了3個(gè)標(biāo)志位

END_STREAM 流結(jié)束標(biāo)志丧蘸,表示當(dāng)前幀是流的最后一個(gè)幀

END_HEADERS 頭結(jié)束表示漂洋,表示當(dāng)前幀是頭信息的最后一個(gè)幀

PADDED 填充標(biāo)志遥皂,在數(shù)據(jù)Payload里填充無用信息,用于干擾信道監(jiān)聽

對于一個(gè)普通的GET請求來說刽漂,它使用一個(gè)HEADERS幀就可以表達(dá)演训。HEADERS幀會設(shè)置標(biāo)志位END_STREAM和END_HEADERS表示當(dāng)前幀是一個(gè)完整的HEADERS幀,也是一個(gè)完整的HTTP請求流贝咙。

對于一個(gè)普通的GET請求響應(yīng)來說样悟,它使用一個(gè)HEADERS幀和多個(gè)DATA幀就可以表達(dá)。HEADERS幀設(shè)置END_HEADERS表示當(dāng)前幀是一個(gè)完整的HEADERS幀庭猩,后面的DATA幀表示返回的數(shù)據(jù)窟她,對應(yīng)Response Body。在HTTP1.1里面返回的Body長度較大蔼水,就需要分Chunk進(jìn)行傳輸震糖。HTTP2是通過分成多個(gè)DATA幀來進(jìn)行的,最后一個(gè)DATA幀有一個(gè)END_STREAM標(biāo)記表示Body的結(jié)束趴腋。

如果HEADERS太大無法用一個(gè)HEADERS幀表達(dá)吊说,可以后面跟多個(gè)CONTINUATION幀,最后一個(gè)幀附加END_HEADERS標(biāo)志即可优炬。

在服務(wù)器主動向客戶端推送資源時(shí)颁井,同一個(gè)資源流里不使用HEADERS幀,取而代之的是PUSH_PROMISE幀穿剖,表示服務(wù)器承諾客戶端即將推送指定資源數(shù)據(jù)蚤蔓,用于區(qū)別一個(gè)常規(guī)的HTTP GET資源請求。

如果一個(gè)TCP連接正在被用于客戶端從服務(wù)器下載一個(gè)大型文件糊余,那么客戶端取消發(fā)送這個(gè)文件的辦法只有一個(gè),就是關(guān)閉連接单寂。HTTP2則可以在不關(guān)閉連接的情況下終止發(fā)送文件贬芥,客戶端向服務(wù)器發(fā)送一個(gè)RST_STREAM幀通知服務(wù)器停止相應(yīng)的資源流即可。這個(gè)連接還可以繼續(xù)服務(wù)其它的請求宣决。

HTTP2服務(wù)器接收到一個(gè)客戶端的連接時(shí)蘸劈,第一個(gè)要干的事就是和客戶端交換SETTINGS幀信息,告知對方一些交互元信息的設(shè)置尊沸,例如是否開啟服務(wù)器推送威沫,并行的最大流數(shù)量,單幀最大長度等洼专。

在客戶端觀看視頻流時(shí)棒掠,如果服務(wù)器發(fā)送的太慢會影響觀看體驗(yàn),如果發(fā)的太快屁商,會對客戶端的瀏覽器緩存造成壓力烟很。客戶端可以使用WINDOW_UPDATE幀通知服務(wù)器調(diào)整幀窗口大小進(jìn)而控制服務(wù)區(qū)發(fā)送的數(shù)據(jù)速率。

閱讀相關(guān)文章雾袱,關(guān)注微信公眾號/知乎專欄/頭條號【碼洞】

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恤筛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子芹橡,更是在濱河造成了極大的恐慌毒坛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件林说,死亡現(xiàn)場離奇詭異煎殷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)述么,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門蝌数,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人度秘,你說我怎么就攤上這事顶伞。” “怎么了剑梳?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵唆貌,是天一觀的道長。 經(jīng)常有香客問我垢乙,道長锨咙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任追逮,我火速辦了婚禮酪刀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钮孵。我一直安慰自己骂倘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布巴席。 她就那樣靜靜地躺著历涝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漾唉。 梳的紋絲不亂的頭發(fā)上荧库,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音赵刑,去河邊找鬼分衫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛料睛,可吹牛的內(nèi)容都是我干的丐箩。 我是一名探鬼主播摇邦,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼屎勘!你這毒婦竟也來了施籍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤概漱,失蹤者是張志新(化名)和其女友劉穎丑慎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓤摧,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡竿裂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了照弥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腻异。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖这揣,靈堂內(nèi)的尸體忽然破棺而出悔常,到底是詐尸還是另有隱情,我是刑警寧澤给赞,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布机打,位于F島的核電站,受9級特大地震影響片迅,放射性物質(zhì)發(fā)生泄漏残邀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一柑蛇、第九天 我趴在偏房一處隱蔽的房頂上張望芥挣。 院中可真熱鬧,春花似錦耻台、人聲如沸九秀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至痹换,卻和暖如春征字,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娇豫。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工匙姜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冯痢。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓氮昧,卻偏偏與公主長得像框杜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子袖肥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容