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