QUIC探索(一):初識(shí)QUIC

前言

此系列會(huì)以一系列文章來(lái)介紹Google在傳輸層的新開(kāi)源貢獻(xiàn):QUIC協(xié)議 的一些內(nèi)容儒洛,也是傳說(shuō)中未來(lái)的HTTP3蔚携。
當(dāng)然希太,系列開(kāi)篇肯定要先介紹QUIC是什么,能做什么酝蜒,為什么要用QUIC這些哲學(xué)問(wèn)題誊辉,所以這篇文章不會(huì)涉及一些代碼層面的東西。

QUIC是什么

QUIC(全稱Quick UDP Internet Connections)是谷歌公司制定的一種基于 UDP 協(xié)議的低時(shí)延互聯(lián)網(wǎng)傳輸協(xié)議亡脑,它提供了多項(xiàng)改進(jìn)堕澄,旨在加速HTTP傳輸并使其更加安全邀跃,目標(biāo)是想最終取代TCP和TLS協(xié)議。
可以用一個(gè)公式大致概括如下:

TCP + TLS + HTTP2 = UDP + QUIC + HTTP2’s API蛙紫。

【注意以上都是去別人家摘錄的】

請(qǐng)注意拍屑,QUIC是由Google最早提出并在chromium實(shí)現(xiàn),而現(xiàn)今交給IETF推進(jìn)標(biāo)準(zhǔn)化工作坑傅。所以當(dāng)前QUIC有兩大分支流派丽涩,一種是基于Google的Chromium工程的QUIC實(shí)現(xiàn),也叫做gQUIC裁蚁;另外一種是標(biāo)準(zhǔn)化進(jìn)行中的版本也叫做iQUIC矢渊。

目前兩者由于協(xié)議格式、加密方式等等的不同而不能互通枉证。當(dāng)然從現(xiàn)時(shí)QUIC協(xié)議開(kāi)源庫(kù)支持度矮男、穩(wěn)定性和多平臺(tái)兼容來(lái)看,比較建議采用Google主導(dǎo)的gQUIC室谚,并且gQUIC在后續(xù)也會(huì)打通與iQUIC的兼容毡鉴。

還有一點(diǎn)就是對(duì)于QUIC版本的話,在Google的源碼更新進(jìn)度上面看其版本迭代非常迅速秒赤,所以這里強(qiáng)烈不建議一味求新猪瞬,除非你是大神或者想當(dāng)小白鼠除外,因?yàn)槊恳粋€(gè)版本的升級(jí)導(dǎo)致新版本的協(xié)議格式和API變動(dòng)較大而忙于處理變更入篮。這里建議從一個(gè)穩(wěn)定的版本進(jìn)行入手研究陈瘦,例如業(yè)界廣泛支持的QUIC43/44。

QUIC的優(yōu)勢(shì)

低延遲連接的建立

對(duì)于傳統(tǒng)的HTTPS來(lái)說(shuō)潮售,對(duì)于其傳輸層的TCP握手就需要3個(gè)RTT痊项,如果算上加密部分的話還需要產(chǎn)生額外的RTT,也就是說(shuō)HTTPS進(jìn)行一次完全的握手至少需要4個(gè)以上的RTT酥诽。
然而對(duì)于QUIC來(lái)說(shuō)鞍泉,如果是客戶端首次連接到服務(wù)器,由于QUIC將傳輸與加密結(jié)合在一起的特性所在肮帐,一般來(lái)說(shuō)正常情況下初次握手只需要1個(gè)RTT就可以完成握手咖驮;但是對(duì)于觸發(fā)版本協(xié)商、證書(shū)無(wú)法解密等問(wèn)題當(dāng)然也會(huì)導(dǎo)致多個(gè)RTT的產(chǎn)生训枢。
而重復(fù)連接的情況下握手托修,如果在證書(shū)有效的情況下,客戶端發(fā)送Hello包并不用等待回復(fù)就可以直接發(fā)數(shù)據(jù)加密包肮砾,也就是實(shí)現(xiàn)了傳說(shuō)中的0RTT诀黍。

改進(jìn)的擁塞控制

TCP 的擁塞控制實(shí)際上包含了四個(gè)算法:慢啟動(dòng),擁塞避免仗处,快速重傳眯勾,快速恢復(fù)枣宫。
QUIC協(xié)議當(dāng)前默認(rèn)使用TCP的擁塞控制算法,并在其基礎(chǔ)上進(jìn)行了相應(yīng)的改進(jìn)吃环;當(dāng)然QUIC也支持其他的擁塞控制算法也颤。
主要的改進(jìn)點(diǎn)有:
1、可插拔設(shè)計(jì)
2郁轻、單調(diào)遞增的Packet Number
3翅娶、不允許Reneging
4、更多的Ack塊
5好唯、精確計(jì)算RTT時(shí)間

無(wú)隊(duì)頭阻塞的多路復(fù)用

HTTP2的最大特性就是多路復(fù)用竭沫,而HTTP2最大的問(wèn)題就是隊(duì)頭阻塞。
首先了解下為什么會(huì)出現(xiàn)隊(duì)頭阻塞骑篙。比如HTTP2在一個(gè)TCP連接上同時(shí)發(fā)送3個(gè)Stream蜕提,其中第2個(gè)Stream丟了一個(gè)Packet,TCP為了保證數(shù)據(jù)可靠性靶端,需要發(fā)送端重傳丟失的數(shù)據(jù)包谎势,雖然這時(shí)候第3個(gè)數(shù)據(jù)包已經(jīng)到達(dá)接收端,但被阻塞了杨名,這就是所謂的隊(duì)頭阻塞脏榆。
而QUIC多路復(fù)用可以避免這個(gè)問(wèn)題,因?yàn)镼UIC的丟包台谍、流控都是基于Stream的须喂,所有Stream是相互獨(dú)立的,一條Stream上的丟包典唇,不會(huì)影響其他Stream的數(shù)據(jù)傳輸镊折。

前向糾錯(cuò)

QUIC協(xié)議的每個(gè)數(shù)據(jù)包除了本身的數(shù)據(jù)以外,會(huì)帶有其他數(shù)據(jù)包的部分?jǐn)?shù)據(jù)介衔,在少量丟包的情況下,可以使用其他數(shù)據(jù)包的冗余數(shù)據(jù)完成數(shù)據(jù)組裝而無(wú)需重傳骂因,從而提高數(shù)據(jù)的傳輸速度炎咖。具體實(shí)現(xiàn)類似于RAID5,將N個(gè)包的校驗(yàn)和(異或)建立一個(gè)單獨(dú)的數(shù)據(jù)包發(fā)送寒波,這樣如果在這N個(gè)包中丟了一個(gè)包可以直接恢復(fù)出來(lái)乘盼,除此之外還可以用來(lái)校驗(yàn)包的正確性。

連接遷移

對(duì)于TCP協(xié)議來(lái)說(shuō)俄烁,標(biāo)識(shí)一個(gè)TCP連接需要4個(gè)參數(shù)绸栅,既來(lái)源IP、來(lái)源端口页屠、目的IP和目的端口粹胯。其中的任一參數(shù)改變蓖柔,TCP連接就需要重新創(chuàng)建。這對(duì)于傳統(tǒng)網(wǎng)絡(luò)來(lái)說(shuō)影響不大风纠,因?yàn)閬?lái)源和目的IP相對(duì)固定况鸣。但是在無(wú)線網(wǎng)絡(luò)中,情況就大不相同了竹观。設(shè)備在移動(dòng)過(guò)程中镐捧,可能會(huì)因?yàn)榫W(wǎng)絡(luò)切換(如從WIFI網(wǎng)絡(luò)切換到4G網(wǎng)絡(luò)環(huán)境),導(dǎo)致TCP連接需要重新創(chuàng)建臭增。
QUIC協(xié)議使用了UDP協(xié)議懂酱,不再需要這四元組參數(shù)。同時(shí)QUIC協(xié)議實(shí)現(xiàn)了自己的會(huì)話標(biāo)記方式誊抛,稱為連接UUID列牺。當(dāng)設(shè)備網(wǎng)絡(luò)環(huán)境切換時(shí),連接UUID不會(huì)發(fā)生變化芍锚,因此無(wú)需重新進(jìn)行握手昔园。

PS:基于QUIC相對(duì)于TCP的優(yōu)點(diǎn)的網(wǎng)上文章已經(jīng)爛大街了,其主要是出自Google的文檔翻譯并炮。這里簡(jiǎn)單的進(jìn)行了一些的介紹就過(guò)了默刚,如果還想進(jìn)一步了解的話建議參考其他文章或者Google發(fā)布的QUIC相關(guān)的文檔,但是對(duì)于開(kāi)發(fā)實(shí)戰(zhàn)意義并非是非常重要的逃魄,只要還是源碼為王荤西,暫時(shí)覺(jué)得只是合適吹水 O(∩_∩)O

QUIC相關(guān)開(kāi)源庫(kù)

chromium:quic-client/server-demo模塊

參考地址:https://www.chromium.org/quic
Google提供的一個(gè)QUIC的源碼使用Demo,但是值得注意的其是封裝了支持HTTPS的QUIC實(shí)現(xiàn)伍俘,如果你想在模仿TCP Socket進(jìn)行QUIC傳輸開(kāi)發(fā)的話這個(gè)方案可能不適合你邪锌。
重點(diǎn)敲黑板,這個(gè)Demo主要用于集成測(cè)試癌瘾,其并不具備大規(guī)模的生產(chǎn)環(huán)境使用的性能的可能性觅丰;換句話說(shuō),它就只是一個(gè)玩具妨退,但是這個(gè)玩具挺值得你去玩味妇萄。
PS:后續(xù)會(huì)有一篇該部分的源碼簡(jiǎn)單剖析的文章。

chromium:net模塊

參考地址:https://chromium.googlesource.com/chromium/src.git
如果你想在Android咬荷、iOS冠句、Linux上面更靈活的使用QUIC的話,我覺(jué)得chromium的net模塊是你的最好選擇幸乒。
如果你需要封裝QUIC在HTTP/HTTPS上面使用的話懦底,可以參考上面的 quic-client/server-demo 的源碼的相關(guān)使用方法,其實(shí)也就主要是研究QUIC源碼庫(kù)在spdy部分的內(nèi)容罕扎。
如果你需要封裝QUIC在更底層模仿TCP Socket操作的話聚唐,不妨看看quartc這個(gè)模塊下面的API實(shí)現(xiàn)丐重,具體的參考net下面的 quartc_session_test.cc 這個(gè)文件或者參考github上面的開(kāi)源庫(kù)posix_quic,不過(guò)后者是基于libquic的拱层,API的調(diào)用流程并不一定適合你開(kāi)發(fā)的版本弥臼,但是可以提供大方向的參考。
PS:后續(xù)的文章也大部分是基于這個(gè)模塊展開(kāi)根灯。

quic-go

參考地址:https://github.com/lucas-clemente/quic-go
quic-go是使用Go語(yǔ)言來(lái)重寫(xiě)的QUIC協(xié)議實(shí)現(xiàn)庫(kù)径缅,從github上面看其對(duì)于iQUIC和gQUIC這兩個(gè)分支流派都提供了支持,這個(gè)庫(kù)當(dāng)前也是比較活躍的烙肺。
從測(cè)試結(jié)果來(lái)看其穩(wěn)定性和對(duì)于多端的支持相對(duì)于chromium來(lái)說(shuō)仿佛就是一個(gè)小弟弟纳猪,但其也不能掩蓋這個(gè)就是以前我們爸媽口中別人家的好孩子般存在。當(dāng)然其性能還需要打磨桃笙,對(duì)于大規(guī)模線上應(yīng)用還是需要謹(jǐn)慎考慮氏堤。

libquic

參考地址:https://github.com/devsisters/libquic
libquic已經(jīng)有多年沒(méi)有更新了,其應(yīng)該是民間從chromium中提取QUIC相關(guān)源碼以及其依賴項(xiàng)而形成一個(gè)簡(jiǎn)易的開(kāi)源代碼庫(kù)搏明,對(duì)于苦于需要找個(gè)梯子下載動(dòng)輒數(shù)十個(gè)GB的chromium源碼開(kāi)發(fā)者來(lái)說(shuō)鼠锈,無(wú)疑是一個(gè)福音,這個(gè)庫(kù)很方便我們快速嘗試QUIC的開(kāi)發(fā)星著。
其支持 ninja 和 cmake 兩種編譯方式购笆,但是遺憾的是從反饋上來(lái)看這個(gè)庫(kù)并不支持iOS平臺(tái)的編譯。
基于這個(gè)平臺(tái)的 HTTP 封裝實(shí)現(xiàn)有 goquic 和 TCP Socket 封裝實(shí)現(xiàn)有 posix_quic虚循。

proto-quic

參考地址:https://github.com/google/proto-quic
這個(gè)庫(kù)是Google在chromium上面抽取出來(lái)發(fā)布于github的一個(gè)快速驗(yàn)證QUIC的開(kāi)源庫(kù)同欠,同libquic一樣并不需要下載太多的源碼,但是其僅僅保證在Ubuntu上是可用的横缔,現(xiàn)在Google已經(jīng)轉(zhuǎn)向了quiche這個(gè)開(kāi)源分支上面進(jìn)行獨(dú)立QUIC庫(kù)的開(kāi)發(fā)铺遂。
在筆者寫(xiě)這篇文章的時(shí)候,其github上面的代碼已經(jīng)被清空茎刚;不難預(yù)期這個(gè)源碼被整個(gè)刪庫(kù)跑路的日子也不會(huì)太遠(yuǎn)了襟锐。

quiche

參考地址:https://quiche.googlesource.com/quiche
更新速度極快的谷歌QUIC開(kāi)源代碼庫(kù),其主要目的是希望將QUIC從chromium這個(gè)龐大的庫(kù)獨(dú)立出來(lái)作為其上游的實(shí)現(xiàn)方案來(lái)提供QUIC協(xié)議的支持膛锭,但是由于其也只是剛剛開(kāi)始從 https://cs.chromium.org/chromium/src/net/third_party 中遷移過(guò)來(lái)捌斧,目前相關(guān)文檔比較缺乏而且源碼結(jié)構(gòu)變動(dòng)過(guò)大;暫時(shí)并不建議入手研究泉沾,但是強(qiáng)烈建議重點(diǎn)關(guān)注。

chromium:Cronet模塊

參考地址:https://developer.android.com/guide/topics/connectivity/cronet
Cronet主要為chromium的net模塊進(jìn)行了Android/iOS端的封裝妇押,并提供了相應(yīng)的Java和OC接口跷究,所以我們?cè)谝苿?dòng)端也是可以通過(guò)Cronet使用net模塊里面QUIC協(xié)議。如果在客戶端APP想要快速驗(yàn)證使用基于QUIC的HTTP請(qǐng)求的話敲霍,Cronet是一個(gè)非常合適的方案俊马,但是在簡(jiǎn)單使用的前提下其靈活性也相對(duì)較差丁存。

Stellite

參考地址:https://github.com/line/stellite
這個(gè)是利用了Cronet,用C++封裝了一層API而得到的這個(gè)Stellite開(kāi)源庫(kù)柴我,解決了我們希望能在C/C++層面進(jìn)行簡(jiǎn)單快速使用QUIC相關(guān)協(xié)議的需求解寝。當(dāng)然,對(duì)于靈活性和效率肯定沒(méi)有比不上chromium的原生邏輯實(shí)現(xiàn)艘儒。

Caddy

參考地址:https://github.com/mholt/caddy
Caddy是當(dāng)前支持QUIC的一個(gè)比較健壯的Web服務(wù)器聋伦,其底層是基于quic-go的實(shí)現(xiàn)。相對(duì)于nginx等框架還未提供對(duì)quic的支持界睁,實(shí)驗(yàn)性支持quic的caddy也是當(dāng)前web服務(wù)器支持QUIC協(xié)議的唯一理想選擇觉增。

結(jié)語(yǔ)

好了,這篇文章主要目的就是簡(jiǎn)單介紹一下QUIC這個(gè)協(xié)議翻斟,以及可用于研究QUIC的一些開(kāi)源庫(kù)逾礁,接下來(lái)主要會(huì)圍繞chromium庫(kù)來(lái)介紹一下基于QUIC的相關(guān)開(kāi)發(fā)工作。

本文發(fā)布于 簡(jiǎn)書(shū)访惜。

End!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嘹履,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子债热,更是在濱河造成了極大的恐慌砾嫉,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钾埂,警方通過(guò)查閱死者的電腦和手機(jī)甲锡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)顾复,“玉大人,你說(shuō)我怎么就攤上這事〖鼍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵避消,是天一觀的道長(zhǎng)低滩。 經(jīng)常有香客問(wèn)我,道長(zhǎng)岩喷,這世上最難降的妖魔是什么恕沫? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮纱意,結(jié)果婚禮上婶溯,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好迄委,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布褐筛。 她就那樣靜靜地躺著,像睡著了一般叙身。 火紅的嫁衣襯著肌膚如雪渔扎。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天信轿,我揣著相機(jī)與錄音晃痴,去河邊找鬼。 笑死虏两,一個(gè)胖子當(dāng)著我的面吹牛愧旦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播定罢,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼笤虫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了祖凫?” 一聲冷哼從身側(cè)響起琼蚯,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惠况,沒(méi)想到半個(gè)月后遭庶,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡稠屠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年峦睡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片权埠。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡榨了,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出攘蔽,到底是詐尸還是另有隱情龙屉,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布满俗,位于F島的核電站转捕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏唆垃。R本人自食惡果不足惜五芝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辕万。 院中可真熱鬧与柑,春花似錦谤辜、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涡戳。三九已至结蟋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渔彰,已是汗流浹背嵌屎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恍涂,地道東北人宝惰。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像再沧,于是被迫代替她去往敵國(guó)和親尼夺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • 本文來(lái)自于騰訊 Bugly 公眾號(hào)(weixinBugly)炒瘸, 作者:emilymmwang淤堵,未經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)...
    Erbash閱讀 6,764評(píng)論 2 12
  • 科普:QUIC 協(xié)議原理分析 作者介紹:lancelot顷扩,騰訊資深研發(fā)工程師拐邪。目前主要負(fù)責(zé)騰訊 stgw(騰訊安全...
    吸霾少年閱讀 9,764評(píng)論 0 19
  • 今天是幼兒園家長(zhǎng)繪本分享日 起床:五點(diǎn)半 就寢:應(yīng)該就是晚上九點(diǎn)半,每天都是這個(gè)點(diǎn) 天氣:天氣預(yù)報(bào)報(bào)的多云 心情:...
    木星上閱讀 121評(píng)論 0 0
  • 今天要拆的書(shū)是《史上最簡(jiǎn)單的問(wèn)題解決手冊(cè)》的片段。 I:片段中講了送禮的兩個(gè)思考的角度婶芭,一個(gè)是認(rèn)識(shí)時(shí)間的長(zhǎng)短东臀,一個(gè)...
    Mr紹君閱讀 288評(píng)論 0 0
  • 近日一篇公號(hào)文章《一個(gè)出身寒門(mén)的狀元之死》,成為10萬(wàn)+閱讀的爆款文章雕擂,刷屏朋友圈啡邑。 文章描述的是一個(gè)...
    深圳的高中生閱讀 656評(píng)論 1 6