提速 30%!腾讯TQUIC 网络传输协议
作者:騰訊 sTGW-TQUIC
騰訊sTGW如何助力核心業(yè)務(wù)用戶登錄耗時(shí)降低30%,下載場景500ms內(nèi)請求成功率從HTTPS的60%提升到90%,移動(dòng)端APP在弱網(wǎng)、跨網(wǎng)場景下同樣取得媲美正常網(wǎng)絡(luò)的用戶體驗(yàn)。
騰訊核心業(yè)務(wù)用戶登錄耗時(shí)降低 30%,下載場景 500ms 內(nèi)請求成功率從 HTTPS 的 60%提升到 90%,騰訊的移動(dòng)端 APP 在弱網(wǎng)、跨網(wǎng)場景下取得媲美正常網(wǎng)絡(luò)的用戶體驗(yàn)。這是騰訊網(wǎng)關(guān) sTGW 團(tuán)隊(duì)打造的 TQUIC 網(wǎng)絡(luò)協(xié)議棧在實(shí)時(shí)通信、音視頻、在線游戲、在線廣告等多個(gè)騰訊業(yè)務(wù)落地取得的成果。TQUIC 基于下一代互聯(lián)網(wǎng)傳輸協(xié)議 HTTP3/QUIC 深度優(yōu)化,日均請求量級(jí)突破千億次,在騰訊云 CLB、CDN 開放云客戶使用。
本文重點(diǎn)分享了 sTGW 團(tuán)隊(duì)在協(xié)議棧基礎(chǔ)能力、私有協(xié)議、明文傳輸?shù)裙δ?#xff0c;并且針對(duì)弱網(wǎng)場景,分享騰訊如何基于 0-RTT 握手、連接遷移、實(shí)時(shí)傳輸?shù)饶芰椭鷺I(yè)務(wù)用戶體驗(yàn)提升。
一、 QUIC/HTTP3 協(xié)議介紹
QUIC 全稱 quick udp internet connection,“快速 UDP 互聯(lián)網(wǎng)連接”,(和英文 quick 諧音,簡稱“快”)是由 Google 提出的基于 UDP 進(jìn)行可靠傳輸?shù)膮f(xié)議。QUIC 在應(yīng)用層實(shí)現(xiàn)了丟包恢復(fù)、擁塞控制、滑窗機(jī)制等保證數(shù)據(jù)傳輸?shù)目煽啃?#xff0c;同時(shí)對(duì)傳輸?shù)臄?shù)據(jù)具備前向安全的加密能力。HTTP3 則是 IETF(互聯(lián)網(wǎng)工程任務(wù)組)基于 QUIC 協(xié)議基礎(chǔ)進(jìn)行設(shè)計(jì)的新一代 HTTP 協(xié)議。
QUIC/HTTP3 分層模型及與 HTTP2 對(duì)比:
二、 QUIC 核心優(yōu)勢是什么?
1. 0-RTT 建立連接
QUIC 基于的 UDP 協(xié)議本身無需握手,并且它早于 TLS 1.3 協(xié)議,就實(shí)現(xiàn)了自己的 0-RTT 加密握手。下圖分別代表了 1-RTT 握手(首次建連),成功的 0-RTT 握手,以及失敗回退的握手。
2.無隊(duì)頭阻塞的多路復(fù)用
相比于 HTTP/2 的多路復(fù)用,QUIC 不會(huì)受到隊(duì)頭阻塞的影響,各個(gè)流更獨(dú)立,多路復(fù)用的效果也更好。
3.連接遷移
跟 TCP 用四元組標(biāo)識(shí)一個(gè)唯一連接不同,QUIC 使用一個(gè) 64 位的 ConnectionID 來標(biāo)識(shí)連接,基于這個(gè)特點(diǎn),QUIC 的使用連接遷移機(jī)制,在四元組發(fā)生變化時(shí)(比如客戶端從 WIFI 切換到蜂窩網(wǎng)絡(luò)),嘗試“保留”先前的連接,從而維持?jǐn)?shù)據(jù)傳輸不中斷。
4.全應(yīng)用態(tài)協(xié)議棧
QUIC 核心邏輯都在用戶態(tài),能靈活的修改連接參數(shù)、替換擁塞算法、更改傳輸行為。而 TCP 核心實(shí)現(xiàn)在內(nèi)核態(tài),改造需要修改內(nèi)核并且進(jìn)行系統(tǒng)重啟,成本極高。
三、 QUIC 網(wǎng)絡(luò)協(xié)議棧的選型
雖然 QUIC 各個(gè)特性看上去很美好,但需要客戶端/服務(wù)端的網(wǎng)絡(luò)協(xié)議棧都支持 QUIC 協(xié)議。截止目前,除 iOS 15 在指定接口 NSURLSession 及限制條件前提下,支持了 HTTP3,其他系統(tǒng)及主流網(wǎng)絡(luò)庫均不支持 QUIC。
如何讓業(yè)務(wù)快速將 QUIC 協(xié)議用起來,用這些先性加速網(wǎng)絡(luò)性能?QUIC 協(xié)議棧的實(shí)現(xiàn)成本非常高,主要體現(xiàn)在兩方面:實(shí)現(xiàn)復(fù)雜度很高,如上面介紹,QUIC/HTTP3 橫跨傳輸層、安全、應(yīng)用層,相當(dāng)于要把 TCP+TLS+HTTP 重新實(shí)現(xiàn)一次。
QUIC 一直保持著高速發(fā)展,分為 gQUIC(Google QUIC)、iQUIC(IETF-QUIC)兩大類,衍生的 QUIC 子版本有幾十個(gè)。
為了快速把 QUIC 協(xié)議落地,給業(yè)務(wù)提升網(wǎng)絡(luò)性能,我們選擇了開源的 Chromium cronet 網(wǎng)絡(luò)協(xié)議棧作為基礎(chǔ)。Chomium,作為占領(lǐng)全球?yàn)g覽器絕對(duì)地位的 Chrome 的開源代碼,有 Google 強(qiáng)大的研發(fā)團(tuán)隊(duì)支撐,其網(wǎng)絡(luò)協(xié)議棧是一個(gè)相對(duì)獨(dú)立的組件,被稱為 Cronet。
協(xié)議棧完整性:完善的 QUIC 協(xié)議棧,還包括 HTTP2/WEBSOCKET/FTP/SOCKS 協(xié)議;
QUIC 版本支持:支持 gQUIC 和 iQUIC,并且還在不斷保持更新;
跨平臺(tái)性:非常好,基于 chrome 的跨平臺(tái)能力,對(duì)于各類操作系統(tǒng)、終端都有適配。
四、QUIC 協(xié)議棧的工程實(shí)踐
Cronet 能直接用起來嗎?結(jié)合我們的實(shí)踐與業(yè)務(wù)同學(xué)的反饋,直接使用的問題和接入困難度是比較大的。
問題一:代碼體積過大,邏輯層級(jí)多,不利于集成和安裝包體積控制(移動(dòng)端)
Cronet 核心及關(guān)聯(lián)的第三方庫代碼有大概 85w 行,涉及 2800 多個(gè)類。但其實(shí) Cronet 里大部分代碼都與 QUIC 沒有關(guān)系,由于其作為瀏覽器的網(wǎng)絡(luò)協(xié)議棧,集成了大量瀏覽器行為邏輯,而這些能力對(duì)于網(wǎng)絡(luò)協(xié)議棧是不需要的。
其次,QUIC 協(xié)議只是 Cronet 里眾多通信協(xié)議之一,除 QUIC 外的其他協(xié)議,通用的平臺(tái)或軟件(例如 Nginx)本身就已經(jīng)有實(shí)現(xiàn),沒有必要重復(fù)建設(shè),這些協(xié)議的存在除了增加協(xié)議棧內(nèi)部邏輯復(fù)雜度,還增大了整個(gè)庫的體積,例如在安卓平臺(tái)上,cronet 動(dòng)態(tài)庫的體積接近 3MB,這對(duì)于一些體積敏感的應(yīng)用是一個(gè)巨大的挑戰(zhàn)。
針對(duì)體積問題,我們進(jìn)行了代碼精簡和 lib 體積縮減的探究。
第一步,分析歸納
通過對(duì) cronet 代碼的分析和理解,冗余的代碼被我們分成了三種:
無用的內(nèi)部邏輯,例如 HTTP 模塊里包含了很多瀏覽器才會(huì)用到的代碼和功能;
無需用到的的協(xié)議,例如 FTP、Websocket 等;
與 quic 無關(guān)的功能模塊,例如 tcp 連接池等。
第二步,代碼裁剪
針對(duì)分析歸納中的三種問題,我們做了針對(duì)性的裁剪。首先是精簡了關(guān)鍵類,例如協(xié)議管控的類中,核心流程步驟被從 21 步壓縮到了 5 步,函數(shù)數(shù)量從 146 個(gè)減少到 24 個(gè),將瀏覽器相關(guān)的冗余邏輯去除。
接著對(duì)用不到的協(xié)議類型、模塊組件做了剔除。裁剪后的效果如下:
五、打磨協(xié)議棧的易用性
雖然在工程方向,解決了體積大小和編譯集成的問題。實(shí)際接入使用時(shí),Cronet 的易用性依然不夠好。
通過挖掘業(yè)務(wù)需求,尋找共性,我們整理出了如下痛點(diǎn):
在通道直連方面,我們將底層 udp socket 粒度的接口進(jìn)行封裝后直接對(duì)外可見,用戶可通過 socket 粒度的接口直接發(fā)起 IP 直連的 QUIC 請求,同時(shí)也保留了 DNS 建連能力,在保持原生能力的同時(shí),拓展了用戶的使用場景。
在網(wǎng)絡(luò)參數(shù)配置和性能數(shù)據(jù)打點(diǎn)能力上,我們深入?yún)f(xié)議棧細(xì)節(jié),逐個(gè)分析了多個(gè)核心模塊,將關(guān)鍵的參數(shù)和性能數(shù)據(jù)抽象出來。并且在控制面上將配置參數(shù)、性能打點(diǎn)整合對(duì)外呈現(xiàn)。
六、進(jìn)階之路:私有協(xié)議和明文傳輸
除了基礎(chǔ)功能的打磨,TQUIC 協(xié)議棧也提供了進(jìn)階功能進(jìn)一步滿足業(yè)務(wù)豐富的使用需求。在 Cronet 中,要想使用 QUIC 協(xié)議,應(yīng)用層傳輸?shù)膱?bào)文必須是 HTTP,也就是所謂的 HTTP3 協(xié)議。但 HTTP 報(bào)文對(duì)于游戲、音視頻等業(yè)務(wù)是個(gè)巨大的阻礙,它們當(dāng)前都是通過 TCP 或者 UDP 傳輸自定義的協(xié)議的,如果為了接入 QUIC 而把應(yīng)用層數(shù)據(jù)從私有協(xié)議強(qiáng)行改為 HTTP3,無疑是本末倒置。另外,由于是自定義協(xié)議,這些報(bào)文一般不需要 QUIC 進(jìn)行加密,但加密是 QUIC 協(xié)議的標(biāo)配,這會(huì)消耗額外的性能。
為此,在仔細(xì)研究了 Quic 核心代碼后,我們研發(fā)對(duì)私有協(xié)議、明文傳輸?shù)闹С?#xff0c;來滿足業(yè)務(wù)傳輸自定義協(xié)議的需求。首先是在 QuicStream 中,允許 stream 直接收發(fā)數(shù)據(jù)報(bào)文,HTTP 流程只是其中一個(gè)選擇。
為了實(shí)現(xiàn)明文傳輸,如果直接去改加解密流程,對(duì)代碼的入侵較大,如果考慮不周容易引入未知風(fēng)險(xiǎn)。為了盡量較少代碼入侵以及維護(hù)原生實(shí)現(xiàn)的安全運(yùn)行,我們將 QuicFramer 中的加解密套件選擇處進(jìn)行了 hook,引入了 FakeEncrypt/FakeDecrypt 替換真實(shí)的加解密套件,以極小的入侵代價(jià)低成本的實(shí)現(xiàn)了明文傳輸。
在做完明文傳輸方案后,我們意識(shí)到由于這是一個(gè)非常底層的修改,對(duì)于客戶端和服務(wù)端來需要高度一致的,要么雙端都選擇加密,要么雙端都選擇明文。如果雙端不統(tǒng)一,則握手就會(huì)失敗。為了使兼容性更好,減少運(yùn)維成本和失敗風(fēng)險(xiǎn),我們在握手協(xié)商過程中,加入了明文傳輸?shù)膮f(xié)商。
如下圖流程,當(dāng)前的握手過程,使用了 AEAD 這個(gè) tag 標(biāo)識(shí)了待協(xié)商的加密算法。
改進(jìn)后,AEAD 可以攜帶明文的加密算法,客戶端如果也認(rèn)可,則在下一次 CHLO 中選擇該算法,則之后兩邊都進(jìn)行明文傳輸。
七、弱網(wǎng)優(yōu)化之連接遷移
隨著移動(dòng)互聯(lián)網(wǎng)的發(fā)展,移動(dòng)端 APP 的能力越來越強(qiáng)大,我們可以輕松通過手機(jī)進(jìn)行會(huì)議通話、視頻直播、在線游戲等,這類應(yīng)用實(shí)時(shí)性要求很高。而移動(dòng)端的特點(diǎn)是網(wǎng)絡(luò)會(huì)經(jīng)常發(fā)生變化,例如通過手機(jī)進(jìn)行在線會(huì)議的同時(shí),從辦公區(qū)走到電梯,隨著網(wǎng)絡(luò)信號(hào)衰退到切換,APP 需要重新建立連接,這會(huì)觸發(fā)用戶重新登錄,體驗(yàn)很差。前面背景介紹的 QUIC 連接遷移可以做到跨網(wǎng)場景自動(dòng)遷移,業(yè)務(wù)無任何感知。那是不是使用 QUIC 后就可以直接用起來呢?
我們以 Google cronet 為例,在 iOS 下使用 Cronet 進(jìn)行了一次切網(wǎng)嘗試,通過抓包發(fā)現(xiàn)網(wǎng)絡(luò)切換后,quic 其實(shí)進(jìn)行了重新握手,并沒有如預(yù)期內(nèi)的進(jìn)行連接遷移。
通過代碼分析原因后,我們發(fā)現(xiàn) Google 其實(shí)并沒有將連接遷移在各個(gè)系統(tǒng)版本上進(jìn)行支持,僅在安卓平臺(tái)“打折扣”的支持了,他們是在 java 層注冊系統(tǒng)通知才能使用連接遷移,對(duì)于 native 的網(wǎng)絡(luò)庫以及其他操作系統(tǒng)是很不友好的。既然原生實(shí)現(xiàn)并不好用,經(jīng)過我們的改造,使用跨平臺(tái)通用的內(nèi)核層調(diào)用,達(dá)到了預(yù)期的效果,并且不依賴任何特定的操作系統(tǒng)組件。
在逐步的實(shí)踐過程中,我們還發(fā)現(xiàn),如果僅僅是切網(wǎng)時(shí)候發(fā)起連接遷移并不完美。有時(shí)候客戶端處在弱網(wǎng)環(huán)境,wifi 信號(hào)并未徹底斷開,但傳輸數(shù)據(jù)實(shí)際上已經(jīng)有損。為了解決這種場景下的問題,我們建立了一套弱網(wǎng)評(píng)估模型,通過主動(dòng)探測和弱網(wǎng)評(píng)估進(jìn)行啟發(fā)式分析,在數(shù)據(jù)通道有損的情況下,盡可能早的主動(dòng)進(jìn)行連接遷移,減少對(duì)上層業(yè)務(wù)的影響。
通過研發(fā)跨平臺(tái)通用的連接遷移,以及啟發(fā)式主動(dòng)遷移能力,最終在客戶端看到的連接遷移效果如下,當(dāng)切網(wǎng)發(fā)生時(shí),連接并未斷開,無需重連即可續(xù)傳數(shù)據(jù)。
業(yè)務(wù)在使用 QUIC 連接遷移后,對(duì)網(wǎng)絡(luò)切換無感知,數(shù)據(jù)不中斷。
或許有同學(xué)發(fā)現(xiàn)了,這里僅僅講了連接遷移在客戶端上的實(shí)現(xiàn)和效果,畢竟連接遷移后,客戶端源 IP 發(fā)生了變化,云端接入層難道不需要做適配嗎?答案是需要的,sTGW 作為公司云 CLB 和自研的主要七層網(wǎng)關(guān)接入,在 QUIC 連接遷移方面做了完整的解決方案,目前也已經(jīng)將能力開放出來,在 QUIC 集群上全量上線。sTGW 對(duì)于連接遷移的解決方案可參見sTGW 大規(guī)模運(yùn)營 QUIC 之路。
八、弱網(wǎng)優(yōu)化之完全 0-RTT 握手與金融級(jí)前向安全
如下是 GQUIC 的握手流程,原生實(shí)現(xiàn)里,應(yīng)用發(fā)生冷啟動(dòng)時(shí),首先會(huì)進(jìn)行 1RTT 握手,拿到服務(wù)端的證書和 ServerConfig(簡稱 SCFG),隨后 SCFG 會(huì)被作為隨機(jī)數(shù)用于生成非前向安全的密鑰。
因此在下一次發(fā)送數(shù)據(jù)包時(shí),便可用非前向安全的密鑰進(jìn)行加密。直到收到了服務(wù)端發(fā)來的 Server Hello 后,通過類似 DHE 算法生成前向安全秘鑰,自此開始發(fā)送前向安全的數(shù)據(jù)包。
在原生實(shí)現(xiàn)中,SCFG 會(huì)被臨時(shí)存儲(chǔ)在進(jìn)程內(nèi)存堆區(qū),下次發(fā)起新連接或者熱啟動(dòng)時(shí),直接就能進(jìn)入 0-RTT 流程,但冷啟動(dòng)則永遠(yuǎn)是 1-RTT。基于原生的實(shí)現(xiàn)情況,我們針對(duì)握手流程做了兩個(gè)方向的優(yōu)化。
實(shí)現(xiàn) 100% 0-RTT 成功率,用于在握手時(shí)延極其敏感的業(yè)務(wù)上,例如廣告請求、API 調(diào)用、短連接下載等。
強(qiáng)制前向安全,針對(duì)安全敏感型業(yè)務(wù),例如金融業(yè)務(wù),0-RTT 中發(fā)送的非前向安全數(shù)據(jù)包風(fēng)險(xiǎn)遠(yuǎn)高于前向安全數(shù)據(jù)包,因此對(duì)于金融型業(yè)務(wù),可以強(qiáng)制 1-RTT 握手生產(chǎn)前向安全密鑰后,再發(fā)送數(shù)據(jù)包。
改進(jìn)后的兩種握手流程如下圖:
九、弱網(wǎng)優(yōu)化之實(shí)時(shí)傳輸
實(shí)時(shí)傳輸是 QUIC 的一個(gè)拓展功能,目前在 IETF 草稿階段。實(shí)時(shí)傳輸適用于對(duì)數(shù)據(jù)可靠性要求不高,但非常注重?cái)?shù)據(jù)實(shí)時(shí)性的業(yè)務(wù)。例如音視頻傳輸、互動(dòng)游戲等。實(shí)時(shí)傳輸在 QUIC 中的定位,以及與可靠傳輸?shù)膮^(qū)別如下:
相同點(diǎn):
在 QUIC 連接建立、創(chuàng)建 QUIC 數(shù)據(jù)包、數(shù)據(jù)加解密這些基礎(chǔ)功能,不可靠數(shù)據(jù)與可靠數(shù)據(jù)都是共用的。
不可靠傳輸也有擁塞控制、ACK 機(jī)制,與可靠傳輸一致。
不同點(diǎn):
不可靠數(shù)據(jù)不受滑動(dòng)窗口限制,滑窗窗口滿只限制可靠數(shù)據(jù)傳輸。
發(fā)生丟包重傳時(shí),只重傳可靠數(shù)據(jù)幀,不可靠數(shù)據(jù)幀不進(jìn)行重傳。
不可靠數(shù)據(jù)沒有 quic stream 概念,只是 frame 粒度。這其中,一個(gè)關(guān)鍵點(diǎn)在于數(shù)據(jù)是否重傳,IETF 草稿的定義對(duì)這塊比較開放,可以完全不重傳,也可以選擇性重傳。
為此,TQUIC 在實(shí)現(xiàn)實(shí)時(shí)傳輸時(shí),做了靈活的改造,對(duì)于實(shí)時(shí)傳輸?shù)臄?shù)據(jù),提供多種重傳策略供使用者選擇,可以完全不重傳,也可以選擇性重傳某個(gè)重要的數(shù)據(jù)(比如關(guān)鍵幀),我們也在嘗試做動(dòng)態(tài)重傳控制,依托我們的弱網(wǎng)判斷模型,動(dòng)態(tài)調(diào)整重傳策略。
十、總結(jié)
經(jīng)過騰訊 sTGW 團(tuán)隊(duì)持續(xù)投入。TQUIC 在騰訊多個(gè)重要業(yè)務(wù)落地,覆蓋業(yè)務(wù)包括實(shí)時(shí)通信、音視頻、在線游戲、在線廣告等。在登錄成功率、登錄耗時(shí)、握手時(shí)延、下載速度等性能指標(biāo)上均取得了明顯收益。騰訊云客戶通過 CLB 使用 HTTP3 后,延遲降低了超過 20 個(gè)點(diǎn),也歡迎大家接入使用。
附部分業(yè)務(wù)效果總結(jié)如下:
參考列表:
https://datatracker.ietf.org/doc/html/rfc9000
https://datatracker.ietf.org/doc/draft-ietf-quic-datagram/?include_text=1
https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit
https://dl.acm.org/doi/abs/10.1145/3098822.3098842
近期熱文:
大牛書單 | 消息隊(duì)列方向的好書
微信 ClickHouse 實(shí)時(shí)數(shù)倉的最佳實(shí)踐
Golang 編程思維和工程實(shí)戰(zhàn)
騰訊程序員視頻號(hào)最新視頻
總結(jié)
以上是生活随笔為你收集整理的提速 30%!腾讯TQUIC 网络传输协议的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大牛书单 | 消息队列方向的好书
- 下一篇: 程序员妈妈的“work-life bal