淘寶 HTTP3-QUIC 技術演進與實踐
一、引言
下圖示爲手淘網絡協議演進關鍵節點。2015 年爲優化標準 TLS/1.2 握手慢問題,我們自行研製上線了輕量級私有加密協議 Slight SSL 來優化握手與加密問題,在沒有重放攻擊風險時允許將會話協商和數據加密放在一個 TCP 報文中來實現 0-RTT,目前手淘線上流量 HTTP2+SlightSSL 也是主要承載者。與此同時過往問題排查 / 業務接入 / 業務訴求面臨一些疑難或者無法滿足訴求問題,諸如 "WI-FI 下長鏈全失敗降級短鏈 https 可以成功,切換到 4G 網長鏈正常使用(SlightSSL 私有協議被 wifi 防火牆斷開)"、" 你們計劃支持 TLS1.3 嗎?"、" 我們域名接入服務端不支持部署 SlightSSL" 等;另一方面隨着 QUIC RFC9000、HTTP3 RFC9114 正式發佈,將手淘網絡協議演進到 HTTP3/QUIC 不管是解決 Slight SSL 私有協議在業務上痛點,還是爲了提高網絡傳輸性能提升用戶體驗,同時也是當下網絡協議向前演進的大勢所趨。私有化協議帶來高效網絡體驗的同時,歸納起來問題主要集中在以下三點:
-
私有化的協議意味着更定製,需要端到端的部署支持(侵入性)
-
不支持 TLS1.3
-
偶有網絡中間設備因私有協議同時斷開兩端連接
二、TNET 能力演進
TNET 全稱 TAOBAO NET,是在手淘無線化發展和演進中,逐步形成的一套底層網絡基礎能力庫。目前承載了手淘 90%+ 的業務 HTTPs 數據流量(少量域名 AMDC 未配置長鏈協議),作爲集團網絡服務在端側落地的基石,是端上到服務端的長鏈通道端側入口,同時也是端上網絡相關中間件的底層基礎。經過演進完善目前對上層提供豐富可組合的協議搭配,內部對不同協議進行實現 & 抽象適配,對外接口上提供統一的接口,外層只需要在建聯時傳入不同組合協議類型即可,做到真正意義上的簡單易用。目前內部功能上主要有兩大塊:
-
一塊由 SPDY/HTTP2/HTTP3/Custom/HTTP3/Tunnel 對上層滿足 HTTP 網絡請求 / 上傳私有協議通道 / ACCS 消息網絡通道能力(其中標準 TLS 主要爲海外等部分不支持 SlightSSL 部署業務使用,標準 HTTP2 目前採用分支維護未合入手淘主幹,原因主要基於手淘集成下包大小考慮,手淘下 SlightSSL 即滿足業務要求且性能更高)
-
另一塊爲提供自實現 DNS 解析 / traceroute/MTU 探測 / ICMP PING 探測 / IPv4&IPv6 協議棧探測能力,主要偏網絡工具屬性滿足上層對網絡診斷 / 探測能力的支持,以及部分對原生 DNS 接口失敗情況下系統能力的補充。
圖 2.1 TNET 能力架構
三、HTTP3/QUIC 協議升級提性能
端雲升級技術改造方案
XQUIC 作爲手淘自研 IETF QUIC 標準的協議庫具備完全自主可控快速演進的優勢,關於 XQUIC 協議庫的設計部分組內同事已有多篇文檔進行詳細的介紹不再重複,感興趣的可通過本文尾部的相關文章鏈接查看。回到端上 TNET 網絡庫來說,通過適配 XQUIC 庫全面升級增加支持七層 HTTP3 協議和四層 QUIC 協議,同時對外屏蔽掉各協議實現上的差異,上層只需建聯時選擇不同的協議類型即可,滿足多種業務場景下不同訴求。
圖 3.1 XQUIC 手淘集成改造方案
端側降級 & 快恢
端上會先從 amdc 拉取一組策略 (amdc 可以理解爲一個擴展的 httpdns 域名解析服務,不僅會返回域名對應的 ip,還有支持協議等擴展屬性),這時 amdc 會同時下發 http3&http2 協議 (端上優先使用 http3,同時下發 http2 協議是爲確保有兜底長鏈協議),拿到 http3 協議後會先進行 udp 連通性探測規避 udp 受限問題,只有當前網絡環境探測通過後的纔會新建 HTTP3 長鏈,關於探測部分文章後面會有介紹。
圖 3.2 客戶端降級策略
升級效果
大盤升級進度 & 效果
前年在手淘重點聯路完成 IPv4 流量部分的 HTTP3 升級覆蓋,去年隨着 Aserver 主站內網 QUIC IPv6 鏈路改造完成,我們將導購 / 交易 / 短視頻 / 上傳鏈路原先走 TCP+IPv6 這部分流量也全部切到 QUIC,目前手淘裏這幾個重點場景已完成全部覆蓋升級。效果上大盤 / 業務 AB 數據顯示 HTTP3/QUIC 在這些不同類型業務場景下都取得顯著提升,助力業務實現好網(傳輸速率 / 均值耗時)更好,弱網(長尾耗時 & 成功率)更優,爲用戶帶來更順滑的網絡體驗。除此之外,阿里集團內其他如菜鳥、手貓、AliExpress 等 APP 也複用我們方案進行 HTTP3 升級覆蓋,拿到更優網絡體驗的業務收益數據。以下是手淘上收益提升情況:
-
導購場景:網絡總耗時均值 / P99 降低 22%/33%,一秒完成率提升 1.2pt;
-
交易場景:網絡總耗時均值 / P99 降低 23%/32%,一秒完成率提升 0.55pt;
-
上傳場景:視頻 / 圖片 上傳速率提升 7.7%/21%,成功率提升 0.18pt;
-
短視頻下載:網絡總耗時均值 / P99 降低 15%/16%,下載速率提升 18%;
圖 3.3 MTOP RPC 核心鏈路升級對比數據
圖 3.4 上傳 & 短視頻內容鏈路升級對比數據
典型業務場景效果
互動場景中斷率
在互動業務下 AB 實驗數據顯示升級 HTTP3 實驗桶可有效降低互動中斷 UV 數 / 流失 UV 數。Android HTTP3 AB 實驗桶中斷 UV 數 / 中斷流失 UV 數分別降低 24.02%/22.89%,IOS 端實驗桶分別降低 20.91%/18.57%。
圖 3.5 手淘互動場景之一笆芭農場
購物車 & 詳情
今年手淘購物車改版後爲用戶下單帶來了便捷,但同時也面臨網絡傳輸體驗上耗時長的業務痛點問題,通過切換到 HTTP3 後從業務大盤耗時均值下降明顯,給業務帶來更多可能。如下圖所示爲 HTTP3 升級推量後接口大盤耗時變化趨勢。其他詳情 / 首頁等接口也有類似表現,這正是由於升級後傳輸性能的提升所帶來。
圖 3.6 業務接口耗時隨着放量趨勢
落地問題 & 優化
UDP 穿透性問題
因部分運營商和網絡中間設備可能存在將 udp 包丟棄的策略,這將拉低大盤建聯成功率並導致降級率顯著變高,往往需要等建聯超時後纔會降級重試成功,這顯然會增加重試耗時導致不好用戶體驗。
對此我們設計了 udp 聯通性探測,在啓動階段或者絡環境發生切換時會觸發異步探測,該探測結果會根據網絡環境持久化到本地,在探測結果過期後會重新觸發探測更新。這樣確保了即使 udp 不通情況下,對上層業務體驗也不會有劣化影響,而在探測通的環境下使用 HTTP3/QUIC 將爲用戶帶來更優的用戶體驗,線上全國大盤的 udp 穿透性探測成功率數據平均值一開始在 95% 左右,經過對 UDP 質量差的 VIP 治理 / 下線歷史不支持 UDP 端口特殊調度配置 / 運營商對某些 UDP IP 網段去黑名單處理,目前全國 udp 探測成功率均值提升到 98%。
UDP 端口 NET-rebind 問題
在 TCP 下五元組便唯一確定一條連接,過往我們 SLB 和 CDN LVS 的負載均衡分發基礎算法都是基於 5 元組來實現,這在 TCP 下可以很好的滿足要求。升級爲 QUIC 協議後基於五元組轉發對連接遷移(Connection Migration)和 多路徑(Multipath QUIC)的能力就無法支持,因爲在這兩類場景下 5 元組都會發生變化。比較理想的是基於 CID 進行一致性 hash 轉發,這也是 QUIC 協議設計之初便與 5 元組解耦考慮,關於基於 CID 分發感興趣的可以查看草案 QUIC-LB。回到我們落地由於涉及到 SLB/LVS 基建改造週期較長,受此影響一開始在單路落地我們基於 5 元組轉發(捨棄掉連接遷移能力)進行業務應用,這在大多數情況下已經滿足要求但也面臨一些問題。NAT 網關針對 UDP 的 Session 存活時間普遍較短,在移動端因爲用戶切後臺空閒情況下容易發生 UDP 端口 NET-rebind 問題,這時通過 5 元組轉發下將無法分發到目標服務器,便會出現因爲找不到連接上下文而導致連接中斷即使當前網絡正常。
如下圖所示,客戶端 QUIC 連接 Q 首先從 NET 設備源出口端口 1 被 SLB 轉發到 Server A 上,連接 Q 從客戶端到 Server A 鏈路雙向轉發傳輸正常;某個時刻如果連接 Q 對應的 UDP Session 空閒(如用戶切後臺)超過 NET 設備保活時間,APP 與出口端口 1 之間映射將失效;等用戶回前臺觸發發包後,NET 設備重新建立起 APP 到出口端口 2 的新映射,此時客戶端上來的包將被 SLB 轉發到另一臺 Server 機器 C 上,而在 C 機器上是找不到 QUIC 連接 Q 對應的上下文,這時會回覆 RESET 導致連接中斷,從我們數據看華爲機型比例高於其他廠商。問題已經清楚通過 CID 轉發來確保端口 NET-rebind 前後路由的一致性,當 Servre 端檢測到新的 5 元組後觸發連接遷移便可得到解決。
圖 3.7、五元組轉發面臨問題
ORTT 比例提升
在首次建連握手時,服務端會給客戶端返回 Session ticket 和傳輸參數,客戶端在 Session ticket 緩存有效期內,下一次握手即可在 client-hello 之後直接發送加密數據。同時 Session ticket 自動到期失效後可以退回 1-RTT 更新,在減少握手延遲的前提下,相較於公鑰預置的方案更優,兼顧前向安全性。手淘上目前在完成首次 1RTT 建聯後,我們會將 Session ticket 和傳輸參數存儲在安全保鏢中以確保緩存的安全性。在項目上線初期,提升效果並不那麼理想,網絡總耗時相較於 H2 提升約 15% 左右,分析數據在首包耗時方面與 H2 幾乎保持持平這顯然不符合預期,通過數據看 0RTT 連接比例一開始只有 40% 左右,經過優化緩存有效率後 0RTT 比例由 40% 提升到了 65%(該比例還有進一步提升空間,短視頻場景 0RTT 比例目前在 80%+),網絡總耗時相較 H2 的提升由 15% 提高到了 20% 左右。
業務非加密訴求
對於一些短視頻業務,響應大小相比 RPC 場景更大,且基本都是明文傳輸對加密訴求弱,更關注視頻拉流的速率。爲此我們在 XQUIC 中實現了加密 / 明文協商能力,在握手完成後如果協商結果爲明文傳輸,則後續包都不再進行加密,這可有效降低 server 端 / 客戶端加解密的處理開銷,進而提升性能。
XQUIC 協議棧性能優化
除前面優化外我們還對協議棧進行深度優化,就 XQUIC 庫本身協議處理性能提升 85.93%,對比 nginx-quic 在處理性能上也有 15.62% 的提升。
圖 3.8 XQUIC 庫協議棧優化對比數據
XQUIC 庫處理模型
下圖是 XQUIC 協議棧最簡化模型:對於發送方而言,XQUIC 會把一段有序字節流封裝成 QUIC 報文發送出去,對於接收方來說,是把一個個無序的 QUIC 報文組裝成一段有序的字節流。
圖 3.9 XQUIC 庫處理簡化模型
整體性優化
我們思考下優化 CPU 開銷的核心是什麼?爲了回答這個問題,我們先想想 CPU 上跑的是什麼?沒錯,就是指令集。那麼指令集是怎麼來的呢?它是由彙編語言生成的。彙編語言是怎麼來的呢?他是由高級編程語言生成的。因此,我們至少可以想到以下三個方面可以優化:
-
編程語言:也就是你的代碼,選擇一個合適的編程語言,然後想辦法寫的性能高一點
-
編譯
-
編譯優化,可以開的編譯優化選項都開起來
-
編譯器,選擇一個高性能的編譯器
-
指令集:這個我們能做的比較少,服務端一般都是 X86
-
組包優化:回到上面的問題,優化 CPU 開銷的核心是什麼?本質上就是減少完成一個功能所需的指令數。注意看 XQUIC 的簡化模型,每收到一個 QUIC 報文,都需要一系列的函數操作,最終輸出一段流。相反的,每發送一段流,都需要調用一系列函數,最終輸出一個個 QUIC 報文。我們要完成的功能就是把一段流傳輸給對端,我們可以優化處理每個包的一系列函數的性能,但是減少函數調用次數是不是來的更高效。減少 QUIC 報文數能大幅提升性能,在協議允許的範圍內儘量填滿每一個報文。
局部性優化
-
能不能不調
-
避免無效計算
-
避免重複計算 :每次加解密包都創建加解密上下文,並且初始化密鑰 -> 握手完成時或者密鑰改變時創建加解密上下文,並且初始化密鑰
-
能不能少調
-
減少內存拷貝:業務拷貝到 H3 層再拷貝到傳輸層 -> 業務拷貝到傳輸層
-
儘早退出循環:特別是遍歷的列表很長時
-
優化函數性能
-
空間換時間 :huffman 解碼錶 用 4K 數組存儲,每次解碼 4bits -> 用 64K 數組存儲,每次解碼 16bits
-
函數內聯
-
分支預測 :likely()/unlikely()
四、集團全鏈路壓測協議升級
amazon 全鏈路平臺升級 HTTP3
在手淘客戶端導購 & 交易場景 HTTP3 大規模放量後,隨之而來的大促全鏈路壓測流量模型中協議佔比也發生改變,全鏈路壓測需同時支持 HTTP2+HTTP3 協議,對此我們對集團全鏈路壓測引擎 amazon 平臺進行一次大的改造升級支持 HTTP3 協議壓測。
不同於 HTTP2 基於 TCP 的已經過多年大促 & 壓測多輪驗證過的穩定鏈路,HTTP3 基於 UDP 的全新鏈路在大促脈衝下的表現則顯得缺少大促經驗,確實通過壓測前驗證助力我們提前發現 UDP 新鏈路下一些問題,針對解決後最終確保雙十一大促 HTTP3 平穩順利。碰到的問題主要有:
- 1、udp_hash 查找性能差問題:在 quic 連接數多的情況下,系統 udp_hash 查找的性能會急劇下降,易打滿系統軟中斷而無法及時處理超時。內核對該問題進行過優化,4.19 之前內核版本需要打 patch,4.19 及之後的版本已自帶,該查找優化需通過設置 socket option 來啓用,爲此我們升級內核版本到 4.19。
setsockopt(s, SOL_UDP, 200, (const void *) &value, sizeof(int)
-
2、內核對 udp 丟包問題:升級 4.19 內核後在 pps 高的情況下又碰到 udp 丟包問題,原因在於 4.19 內核對 udp 內存存在限制。
具體原理:
- 對每個 UDP session 內核會把使用的內存計數,並累積到一定值(與 rcvbuf 正相關)才釋放 2. 內核會記錄所有 UDP 的的內存計數和,當這個計數和大於限制值(與 umem 正相關 )時 ,將會丟棄所有的 UDP 報文。
不難看出該問題會導致我們單機長鏈數和應對突增流量的受限,爲此我們兩個優化參數調節方向:
1、增加 umem 值 2、縮小 recvbuf 值。
五、 正在進行
HTTP3 覆蓋圖片域名
當前我們完成導購、交易、短視頻、上傳鏈路的全量升級覆蓋,圖片域名的升級覆蓋還在逐步灰度覆蓋中。
HTTP3 over MPQUIC 規模化應用
MPQUIC 改造涉及到客戶端、SLB、Aserver 等基建的升級,目前 RPC 鏈路端到端整條鏈路已經改造完成。手淘 Android 已正式上線目前處在規模化放量階段,能力上提供兩種可選模式(長尾補償模式和多路並行加速模式),從灰度數據看加速模式下 MPQUIC 相比單路 QUIC 還有 8% 進一步速率提升,目前 XQUIC 實現的 MPQUIC 已對外開源。CDN 鏈路 MPQUIC 支持改造 Server 端和 LVS 正在進行中。
圖 5.1 WIFI+LTE 雙路聚合傳輸示意圖
附錄
QUIC-LB: https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers-15
RFC 9000:https://quicwg.org/base-drafts/rfc9000.html
RFC 9114:https://quicwg.org/base-drafts/rfc9114.html
XQUIC: https://github.com/alibaba/xquic
團隊介紹
網關與網絡技術隸屬於大淘寶技術 - 大淘寶平臺技術 - 終端體驗平臺團隊,希望能通過網絡技術演進給用戶帶來更絲滑的體驗。如果對 XQUIC、網絡技術、高性能網絡傳輸、網絡成本優化等領域比較感興趣,歡迎點擊 “閱讀原文” 關注我們的 GitHub 倉庫:https://github.com/alibaba/xquic。
如果在使用 XQUIC 相關產品中遇到問題,歡迎加入 XQUIC 社區釘釘羣反饋 & 交流:34059705 。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/uwMxy5v_uwQDCMAUWgWgPw