讓網際網路更快:新一代QUIC協議在騰訊的技術實踐分享

jsjsjjs發表於2018-02-22

本文來自騰訊資深研發工程師羅成在InfoQ的技術分享。

1、前言

如果:你的 App,在不需要任何修改的情況下就能提升 15% 以上的訪問速度,特別是弱網路的時候能夠提升 20% 以上的訪問速度。

如果:你的 App,在頻繁切換 4G 和 WIFI 網路的情況下,不會斷線,不需要重連,使用者無任何感知。如果你的 App,既需要 TLS 的安全,也想實現多路複用的強大。

如果:你剛剛才聽說 HTTP2 是下一代網際網路協議,如果你剛剛才關注到 TLS1.3 是一個革命性具有里程碑意義的協議,但是這兩個協議卻一直在被另一個更新興的協議所影響和挑戰。

如果:這個新興的協議,它的名字就叫做“快”,並且正在標準化為新一代的網際網路傳輸協議。

你願意花一點點時間瞭解這個協議嗎?你願意投入精力去研究這個協議嗎?你願意全力推動業務來使用這個協議嗎?

本文主要介紹 QUIC 協議在騰訊內部及騰訊雲上的實踐和效能優化,新一代的網際網路協議需要大家一起努力推動,你準備好了嗎?

欲瞭解 QUIC 協議產生的背景和核心特性,可閱讀《技術掃盲:新一代基於UDP的低延時網路傳輸層協議——QUIC詳解》。

學習交流:

– 即時通訊開發交流群:320837163[推薦]

– 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

(本文同步釋出於:http://www.52im.net/thread-1407-1-1.html

2、相關文章

技術掃盲:新一代基於UDP的低延時網路傳輸層協議——QUIC詳解

讓網際網路更快:新一代QUIC協議在騰訊的技術實踐分享

七牛雲技術分享:使用QUIC協議實現實時視訊直播0卡頓!

3、本文作者

羅成:騰訊資深研發工程師。目前主要負責騰訊 stgw(騰訊安全雲閘道器)的相關工作,整體推進騰訊內部及騰訊公有云,混合雲的七層負載均衡及全站 HTTPS 接入。對 HTTPS,SPDY,HTTP2,QUIC 等應用層協議、高效能伺服器技術、雲網路技術、使用者訪問速度、分散式檔案傳輸等有較深的理解。(作者微博:點此進入

4、QUIC 在騰訊的實踐

騰訊安全雲閘道器 (STGW) 和騰訊雲負載均衡器(Cloud Load Balance)在 2017 年 7 月份就已經在服務端上支援了 Quic 協議,在工程實現上也有很多優化點,同時在生產環境中也取得了較好的效果。相比現在幾個開源的方案,STGW 的實現主要有如下幾個優點。

1)高效能:

複用 Nginx 全非同步事件驅動框架;

私鑰代理計算叢集加速簽名計算;

全域性快取提速,減少計算量的同時,提升訪問速度。

2)強大的功能:

支援 Nginx 現有全部模組指令,豐富的第三方模組;

複用 Nginx 模組框架,非常靈活地新增第三方功能。

3)穩定性:

程式碼完全自主可控;

正在經受騰訊億萬級併發流量的考驗。

同時我們也在騰訊很多業務包括 QQ 空間、WEB 遊戲頁面、騰訊雲 CLB 上灰度支援了 QUIC 協議。詳細的提升資料可以參考文中線上灰度資料一節。

5、QUIC 選型調研時的測試方案

在決定使用 QUIC 協議之前,我們需要對 QUIC 協議的特性及效能做一個全面的測試,如何測試呢?這裡簡單說一下測試方案。

需要特別說明的測試是在 2016 年底進行的,目前所有域名已經失效,無法再進行測試。

5.1 頁面構造

根據 httparchive.org 的統計,構造瞭如下頁面:

5.2 測試環境

手機:華為 mate9 

User-Agent:MHA-AL00 Build/HUAWEIMHA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36

作業系統:Android 7.0

服務端 QUIC 程式:caddy 0.9.4

網站和客戶端分佈如下:

① 表示客戶端主動發起的使用者請求;

② 表示從 html 裡發出的資源請求;

③ 表示資料上報請求。

5.3 測試流程

整個測試流程通過 python 指令碼和 adb shell 工具自動化進行,其中移動端和 PC 端的控制流程有所區別。現分別簡介如下。

【移動端測試流程】:

準備事項:

開啟手機的 usb 除錯選項;

在 PC 端安裝 adb;

在 PC 上通過 USB 連線手機,確保能夠通過 adb  devices 命令發現裝置;

在服務端配置 cache-control: no-cache, no-store。禁止客戶端快取。

自動化測試流程如下:

啟動 android chrome;

訪問 https://www.helloworlds.cc

待頁面載入完後會觸發 onload 事件,將各個時間點上報。

【PC 端流程】:

PC 端不需要 adb,使用 webbrowser 模組控制 chrome 完成即可。

5.4 測試結論

由於公司內網的 WIFI 環境不穩定,多次測試發現資料跳動較大,4G 環境下的資料更加穩定可靠,所以主要結論參考 4G 網路下的資料。

測試結果顯示,QUIC 的優勢非常明顯:

即使在元素比較少(12 個元素)的情況下:相比 HTTP 也能提升 9%,相比 HTTP2 提升 42%,相比 HTTPS 提升 52%;

在頁面元素增多的情況下:QUIC 的優勢就更加明顯,相比 HTTP 提升 36%,相比 HTTP2 提升 47%,相比 HTTPS 提升 64%。

5.5 優化空間

QUIC 的特性雖然比較先進,但是實現起來卻非常複雜,在工程實現方面也有很多優化的空間。比如如何提升 0RTT 成功率,減少服務端的 CPU 消耗量,實現連線遷移和動態的擁塞控制演算法等。我們繼續看下節。

6、QUIC 效能優化1:提升 0RTT 成功率

安全傳輸層雖然能夠實現 0RTT,優勢非常明顯。但問題是,不是每一次連線都能實現 0RTT,對於我們的客戶端和服務端來講,如何最大程度地提升 0RTT 的成功率?

0RTT 能實現的關鍵是 ServerConfig。就像 TLS session resume 實現的關鍵是 session id 或者 session ticket 一樣。

ServerConfig 到達服務端後,我們根據 ServerConfig ID 查詢本地記憶體,如果找到了,即認為這個資料是可信的,能夠完成 0RTT 握手。

但是會有兩個問題:

1)程式間 ID 資料無法共享;

2)多臺伺服器間的 ID 資料無法共享。

明確了問題,那工程層面就需要實現多程式共享及分散式多叢集的 ID 共享。

SeverConfig Cache 叢集如下圖所示:

如上圖所示,Stgw 在生成 ServerConfig ID 和內容時,會儲存到全域性的 Cache 叢集。使用者握手請求落到任意一臺 STGW 機器,從全域性 Cache 叢集都能找到相應的內容,實現 0RTT 握手。

7、QUIC 效能優化2:加密效能的優化

7.1 簽名計算

QUIC 實現 0RTT 的前提是 ServerConfig 這個內容簽名和校驗都沒有問題。由於 ServerConfig 涉及到 RSA 簽名或者 ECDSA 簽名,非常消耗我們的 CPU 資源。根據之前的測試資料,RSA 私鑰簽名計算會降低 90% 的效能。

那如何優化呢?使用 RSA 或者 ECDSA 非同步代理計算,核心思路也是三點:

演算法分離:剝離私鑰計算部分,不讓這個過程佔用本地 CPU 資源;

非同步執行:演算法剝離和執行非同步的,上層服務不需要同步等待這個計算過程的完成;

平行計算:我們使用配置了專用硬體的私鑰計算叢集來完成私鑰計算。

架構如下圖所示:

7.2 對稱加密的優化

相比非對稱金鑰交換演算法來講,對稱加密演算法的效能非常卓越(好 1 到 2 個數量級),但是如果應用層傳輸內容較大的話,特別是移動端的 CPU 計算能力較弱,對稱加密演算法對效能的影響也不容忽視。

常用對稱加密演算法效能比較:

如何優化呢?通過非同步代理的方式顯然不可能。原因是:

會極大降低使用者訪問速度。由於應用層的每一個位元組都需要對稱加解密,使用非同步的方式實現會嚴重降低加解密的實時性。

那有沒有同步的優化方式呢?有:

類似 SSL 硬體加速卡,intel 針對 AES 演算法實現硬體加速,並將它整合到了 CPU 指令裡。

【AES-NI 指令】:

AES-NI 是 intel 推出的針對 AES 對稱加密演算法進行優化的一系列指令,通過硬體計算實現計算速度的提升。

如何測試 AES-NI 的效能呢?

通過環境變數:aes-ni: OPENSSL_ia32cap=”~0x200000200000000″ openssl speed -elapsed -evp aes-128-gcm 或者在程式碼裡將 crypto/evp/e_aes.c # define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) 進行設定。

aesni 對效能的提升約 20%, 由 4.3W 提升到 5.1W。

這裡需要注意的是,如果需要單獨使用 openssl 的 API 進行 AES 對稱加解密,最好使用 aes evp API,這樣才會預設開啟 AES-NI 指令。

【chacha20-poly1305】:

chacha20-poly1305 是由 Dan Bernstein 發明,並且由 google 推出的一種帶身份認證的對稱加密演算法。其中 chacha20 是指對稱加密演算法,poly1305 指身份認證演算法。這個演算法是對沒有 AES 硬體加速功能的移動平臺的補充,比如 ARM 晶片。

從 google 公佈的資料來看,chacha20-poly1305 能夠提升 30% 以上的加解密效能,節省移動端耗電量。當然,如果手機端支援 AES-NI 指令的話,chacha20 就沒有優勢了。

Openssl 在 1.1.0 版本中正式支援了 chacha20-poly1305。

8、QUIC 效能優化3:連線遷移 (Connection Migration) 的實現

那 STGW 服務端如何實現的呢?我們在 CLB 四層轉發層面實現了根據 ID 進行雜湊的負載均衡演算法,保證將相同 ID 的 QUIC 請求落到相同的 CLB7 層叢集上,在 CLB7 上,我們又會優先根據 ID 進行處理。

QUIC 連線遷移圖示如下:

如上圖所述,客戶端最開始使用 4G 行動網路訪問業務,源 IP 假設為 IP1,整個訪問流程使用藍色線條標識。

當使用者進入 WIFI 網路時,源 IP 發生了變化,從 IP1 切換到了 IP2,整個訪問流程使用綠色線條標識。由於接入的 CLB4 有可能發生變化,但整個 CLB 叢集統一使用 QUIC Connection ID 排程,只要 QUIC 連線的 ID 沒有發生變化,能夠將該請求排程到相同的 CLB7 層機器上。

同一臺 CLB7 儲存了相同的 Stream 及 Connection 處理上下文,能夠將該請求繼續排程到相同的業務 RS 機器。

整個網路和 IP 切換過程,對於使用者和業務來講,沒有任何感知。

9、QUIC 效能優化4:動態的流量控制和擁塞控制

STGW 在連線和 Stream 級別設定了不同的視窗數。

最重要的是,我們可以在記憶體不足或者上游處理效能出現問題時,通過流量控制來限制傳輸速率,保障服務可用性。

10、STGW 針對 QUIC 的效能統計

STGW 針對 QUIC 的線上使用情況進行了很多的變數統計和分析,包括 0RTT 握手成功率,握手時間,密碼套件使用分佈,QUIC 協議版本,stream 併發數量等。

這些統計變數能夠為我們的協議優化提供更加精細的資料支撐。

11、QUIC 線上灰度資料

QUIC 目前已經在 STGW 上線執行。我們針對騰訊幾個重要域名(包括 QQ 黃鑽頁面,遊戲頁面)進行了灰度實驗。

Qzone QUIC 頁面:

如上圖所示,圖中紅色箭頭指向的綠色標識表示該頁面使用了 QUIC 協議。

灰度實驗的效果也非常明顯,其中 quic 請求的首位元組時間 (rspStart) 比 http2 平均減少 326ms, 效能提升約 25%; 這主要得益於 quic 的 0RTT 和 1RTT 握手時間,能夠更早的發出請求。

此外 quic 請求發出的時間 (reqStart) 比 h2 平均減少 250ms; 另外 quic 請求頁面載入完成的時間 (loadEnd) 平均減少 2s,由於整體頁面比較複雜, 很多其它的資源載入阻塞,導致整體載入完成的時間比較長約 9s,效能提升比例約 22%。

上述資料有兩個問題,僅供參考,因為:

由於我們的頁面並沒有全部改造成 QUIC 協議,所以效能資料應該還可以進一步提升;

每個業務的頁面構成不一樣,提升的效能資料也會有差別。

12、我們開源了CLB-QUIC-DEMO的原始碼

前面提到的 QUIC 實踐和優化都是針對服務端。為了方便廣大開發者進一步瞭解 QUIC 在客戶端的使用,我們提供了一個安卓客戶端的 DEMO,僅供參考。

DEMO 已經在 github 上開源,地址如下:

https://github.com/52im/clb-quic-demo

DEMO 的主要目的有兩個:

1)簡單說明一下在客戶端使用 QUIC;

2)簡單對比 HTTP2 和 QUIC 的效能差別。

Demo的使用介面比較簡單,如下所示:

如果有使用者想使用 QUIC 協議,客戶端做一下改造,服務端直接使用騰訊雲 CLB 負載均衡器就能實現了。

如前所述,CLB 在協議計算效能和訪問速度、安全效能方面,做了非常多優化。

13、本文小結

QUIC 協議非常複雜,因為它做了太多事情:

1)為了實現傳輸的可靠性,它基本上實現並且改進了整個 TCP 協議的功能,包括序列號,重傳,擁塞控制,流量控制等;

2)為了實現傳輸的安全性,它又徹底重構了 TLS 協議,包括證照壓縮,握手訊息,0RTT 等。雖然後續可能會採用 TLS1.3 協議,但是事實上是 QUIC 推動了 TLS1.3 的發展;

3)為了實現傳輸的併發性,它又實現了 HTTP2 的大部分特性,包括多路複用,流量控制等。

雖然如此複雜,但是 QUIC 作為一個新興的協議,已經展現了非常強大的生命力和廣闊的前景。

目前國內外除了 Google 大規模採用外,還鮮有其他網際網路公司使用。STGW 作為騰訊的安全雲閘道器,我們有責任,有義務對業界先進的標準協議提供支援和優化。同時騰訊雲也是國內第一家支援 QUIC 協議的雲廠商,因為這個協議能切實改善客戶端的訪問速度和終端使用者體驗。

我們不僅在服務端實現了 Quic 協議的支援,優化了 QUIC 協議方面的效能問題,同時也希望通過自己一些經驗的分享,推動 QUIC 協議的發展,構造一個更加安全更加快速的網際網路世界。

Let’Quic,  Make Web Faster。

(本文同步釋出於:http://www.52im.net/thread-1407-1-1.html


相關文章