得物技術網路優化-CDN資源請求優化實踐

得物技術發表於2022-04-21

1.前言

為使用者提供更加流暢的App使用體驗是我們的目標。作為電商類App,社群+交易相關業務強依賴圖片、視訊、檔案等靜態資源。由於這些靜態資源部署在CDN上,因此本文統稱為“CDN資源”。

雖然部署到CDN服務後提升了CDN資源的請求效能,但只能算是初始階段,App端依然存在資源載入慢、卡頓等體驗問題,離預期還有一定距離,需要進一步優化。因此,2021年下半年我們對CDN資源的網路請求效能進行了重點優化,取得了明顯的效果,本文在此進行一個階段性總結。

2.內容介紹

本文主要介紹得物 CDN 資源請求實現平均耗時 iOS 端降低18%+, Android 端降低10%+ 的優化思路及優化實踐經驗。整體按監控資料分析,優化方向調研,優化方案設計,推進優化落地,優化效果反饋的流程執行,達到逐步優化的效果。本文主要講4個優化方向,包括:CDN部署調整,TLS1.3升級,OCSP Stapling開啟,Http2.0升級。下面就來詳細介紹下每個優化方向具體如何確定的,優化的方案,以及優化效果。

3.優化案例

3.1 CDN部署調整

3.1.1 什麼是CDN服務?

可能有的同學對CDN還不太熟悉,我們先簡單介紹下CDN的概念及原理。CDN(Content Delivery Network)指內容分發網路,由分佈在不同地區的邊緣伺服器節點組成的分散式網路,負責快取源站靜態資源並就近分發給使用者,達到降低靜態資源請求耗時,降低源站伺服器壓力的目的。

CDN服務的優勢:就近接入,資源快取,降低迴源,智慧選路,高效傳輸,智慧壓縮,安全,高效能等特性(摘自阿里雲CDN文件介紹)。簡單來說就是就近接入,資源快取,高效回源這3大特性。

靜態資源部署到CDN服務後,訪問鏈路從請求源站變為就近接入CDN邊緣節點,大大縮短了網路訪問鏈路,降低了CDN資源的請求耗時。如廣東使用者原來請求CDN資源需要訪問杭州源站,現在可以直接訪問廣東省內的CDN邊緣節點獲取CDN資源。

CDN邊緣節點如果有當前請求的CDN資源快取,則直接將快取返回給客戶端;如果沒有快取,則通過CDN服務系統內部策略實現高效回源,資源獲取後返回到CDN邊緣節點並快取,再返回給客戶端。

下圖可以直觀的展現出部署到CDN服務前後使用者請求靜態資源的變化

(注:圖片來自網路)

3.1.2 從地域維度分析CDN資源請求耗時監控資料

瞭解了CDN的原理後,我們就知道,CDN服務效果是和地域強相關的。對不同地區的使用者來說,該地區是否部署了CDN伺服器節點,部署了多少臺CDN伺服器節點來承載流量直接影響著該地區使用者CDN資源請求的耗時長短。因此,考慮先從CDN按地區部署的角度對CDN資源請求監控資料進行分析。

我們重點分析平均耗時大於等於500ms的省份,其中廣東省作為一線省份,網路基礎設施應該比較完善,為什麼平均耗時在500ms以上?

初步推測:可能是CDN伺服器節點部署不合理,未在廣東省部署或在廣東省部署較少,廣東使用者無法就近接入CDN服務,跨域訪問導致CDN資源請求耗時較長。

3.1.3 阿里雲CDN部署情況調研

我們將這個推測反饋給阿里雲客服,讓其核實服務於得物的CDN邊緣節點在各省份的分佈情況以及廣東省CDN邊緣節點的部署情況。

排查結果:未部署廣東、北京,並且湖南、四川、江蘇、吉林部署節點偏少。

調研結論:這些地區的使用者存在跨域請求CDN資源的問題,導致請求平均耗時較長。

3.1.4 CDN部署優化方案

問題原因定位後,解決方案比較簡單,合理調整CDN邊緣節點部署:

1.新增廣東、北京本省節點;

2.新增湖南、四川、吉林、江蘇本省節點,替換外省冗餘節點。

3.1.5 CDN 部署優化效果

CDN域名cdn.poizon.com 優化前後資料:

平均耗時

  1. iOS:429ms -> 331ms,降低98ms

  1. Android:386ms -> 348ms,降低38ms

3.2 TLS1.3升級

一次完整的Https網路請求包含7個階段:請求準備、 DNS 解析、TCP建連、SSL握手、Request階段、服務端處理階段、Response階段

為了更詳細的分析得物CDN資源請求效能資料,我們在App端將每次請求各階段的耗時進行了單獨埋點取樣上報,CDN網路監控平臺提供了按網路請求階段聚合量化的效能指標。因此,對網路請求各階段的監控資料進行分析,看是否有可優化的階段。

3.2.1 從 網路 請求階段維度分析 CDN 資源請求耗時 監控 資料

網路請求階段耗時詳情如下圖

從圖中可以看到,SSL階段平均耗時127ms+,佔累積耗時25%以上。SSL階段耗時對整體耗時影響較大,因此考慮對SSL階段效能優化。

對於Https請求,SSL階段主要是進行金鑰協商,保證資料加密傳輸的。目前得物CDN資源請求使用的是TLS1.2協議,而最新的TLS1.3協議也已經比較成熟,是否可以通過升級TLS1.3協議來實現對SSL階段效能優化的目的呢?

3.2.2 TLS1.3協議調研

TLS1.3協議有哪些優勢?與TLS1.2協議的區別?

TLS(Transport Layer Security Protocol)是傳輸層安全協議,TLS1.2協議2008年釋出,TLS1.3協議2018年釋出。

TLS1.2協議目前使用最廣泛,從2008年釋出到現在13年多的時間裡被發現了一些缺點:

1.效能較差:握手過程需要2個RTT;

2.安全性較低:使用了不安全的加密演算法,如SHA1,RC4,CBC等加密演算法。

TLS1.3協議則是基於TLS1.2進行了大量優化,包括:

1.效能優化:引入了新的金鑰協商機制PSK,握手過程僅需1RTT,比TLS1.2協議降低50%+;

2.安全性提高:廢棄了TLS1.2協議中眾多不安全及老舊的加密演算法,不再使用DSA證書,ServerHello之後的握手資訊都進行了加密等。

友商使用TLS1.3的情況調研

調研友商的CDN資源請求TLS協議,友商App使用的TLS1.3協議,驗證了TLS1.3協議的可行性。

通過Chrome瀏覽器載入友商的圖片,在DevTools視窗的Security皮膚可以看到使用的是TLS1.3協議。

客戶端雙端TLS1.3相容性調研

雙端主流機型已支援TLS1.3,且不支援TLS1.3的機型阿里雲CDN服務也做了相容,會根據客戶端使用的TLS協議版本自動匹配使用對應的TLS協議。

線下測試:使用Debug包線上下環境分別使用TLS1.3協議與TLS1.2協議請求CDN資源,均請求正常。

3.2.3 TLS1.3升級優化方案

TLS1.3相比TLS1.2可以將SSL階段耗時降低50%+,因此採用升級TLS1.3協議的方式實現對CDN資源請求SSL階段耗時的優化,詳細優化方案可以參考之前釋出的一篇文章《得物網路優化-TLS1.3升級最佳實踐》https://mp.weixin.qq.com/s/C0...

3.2.4 TLS1.3升級優化效果

CDN cdn.poizon.com升級TLS1.3後,雙端平均耗時、TLS耗時均有明顯降低,優化前後資料:

平均耗時

  1. iOS:281ms -> 237ms,降低44ms
  2. Android:307ms -> 269ms,降低38ms

SSL階段耗時

  1. iOS:210ms -> 137ms,降低73ms
  2. Android:83ms -> 71ms,降低12ms

3.3 OCSP Stapling開啟

TLS1.3升級後,CDN資源請求效能提升了不少,但雙端SSL階段耗時依然有優化空間,因此繼續調研SSL階段的優化方案。通過調研後發現SSL階段證書交換需要使用OCSP協議驗證SSL證書的有效性。那什麼是OCSP協議呢?OCSP協議是否會對SSL階段效能造成影響?

3.3.1 什麼是OCSP協議?

OCSP(Online Certificate Status Protocol)是線上證書狀態協議,用於驗證SSL證書的有效性,確保SSL證書未被吊銷或過期。CA伺服器提供了線上查詢證書狀態的介面,客戶端可以在SSL階段實時向CA伺服器發起一次證書狀態查詢請求,CA伺服器會回覆證書的狀態資訊(如“有效”,“過期”等)。

由於客戶端在等待查詢結果前是阻塞的,OCSP查詢過程耗時長短就影響了SSL階段耗時。

執行OCSP協議的一次請求過程如下圖

從圖中可以看到,客戶端會多出一次OCSP的查詢過程。為了解決OCSP協議對效能的影響,OCSP Stapling協議應運而生,下面介紹下OCSP Stapling協議。

3.3.2 什麼是OCSP Stapling協議?相比OCSP做了什麼優化?

OCSP Stapling是將證書狀態的查詢過程從客戶端遷移到服務端,由服務端低頻執行OCSP協議請求CA伺服器查詢證書狀態並將查詢結果快取起來,服務端在客戶端請求SSL階段時將證書查詢結果返回給客戶端。

執行OCSP Stapling協議的一次請求過程如下圖

從圖中可以看到,執行OCSP Stapling協議後客戶端可以節省一次OCSP查詢過程。

3.3.3 OCSP Stapling開啟優化調研

友商使用OCSP Stapling的情況調研

調研友商的CDN資源請求OCSP Stapling使用情況,友商的CDN服務已開啟OCSP Stapling,驗證了OCSP Stapling的可行性。

友商的CDN服務是否OCSP Stapling生效的驗證方法:

步驟1:查詢友商CDN域名(如:cdn.xxx.com)的IP,可以使用dig命令

dig cdn.xxx.com

步驟2:通過openssl命令檢視友商CDN域名OCSP Stapling狀態

openssl s_client -connect 步驟1查到的ip:443 -servername cdn.xxx.com -status

結果1:OCSP Stapling生效圖片如下:

可以看到OCSP Response Status:successful(0x0),代表OCSP Stapling已生效

結果2:OCSP Stapling未生效圖片如下:

可以看到OCSP Response:no response sent,代表OCSP Stapling未生效

客戶端雙端OCSP Stapling相容性調研

iOS:系統預設支援OCSP Stapling

Android:暫不支援OCSP過程

阿里雲CDN相容性:

與阿里雲客服已確認阿里雲CDN服務支援OCSP Stapling功能。如果客戶端系統支援OCSP Stapling功能,則開啟後OCSP Stapling功能生效;如果客戶端系統不支援,依然支援使用OCSP方式正常請求。

線下測試:使用Debug包線上下環境分別開啟OCSP Stapling與關閉OCSP Stapling請求CDN資源,均請求正常。主要覆蓋這些方面:

1.反覆驗證:包括反覆開啟/關閉,App冷/熱啟動,App切前後端等操作鏈路;

2.業務主鏈路迴歸:覆蓋社群首頁、社群詳情頁、視訊、交易首頁、商品詳情頁、訂單詳情頁等核心頁面;

3.相容性測試:覆蓋App最近版本,主流機型、主流系統等。

3.3.4 OCSP Stapling開啟優化方案

通過操作阿里雲CDN控制檯開啟OCSP Stapling功能來實現SSL階段耗時進一步優化。

變更執行:凌晨2點在阿里雲CDN控制檯操作開啟OCSP Stapling

驗證方案:如上文描述友商調研方法,使用openssl命令檢視CDN域名cdn.poizon.com OCSP Stapling狀態是否生效

監控方案:

1.網路監控平臺:監控請求異常率、請求耗時等指標是否有異常波動情況;

2.阿里雲CDN-實時監控:分鐘級2xx,3xx,4xx,5xx狀態碼是否有異常波動情況。

3.3.5 OCSP Stapling開啟優化效果

CDN cdn.poizon.com開啟阿里雲OCSP Stapling後iOS端耗時降低明顯,Android端變化不大(Android:暫不支援OCSP過程,因此OCSP Stapling優化對Android暫無作用),優化前後資料:

平均耗時(僅建連)

iOS:565ms ->484ms,降低81ms

Android:401ms -> 360ms,降低41ms

SSL階段耗時

iOS:97ms -> 87ms,降低10ms

Android:79ms -> 70ms,降低9ms

3.4 HTTP2.0升級

3.4.1 從Http協議版本維度進行監控資料分析

檢視CDN域名cdn.poizon.com 2021.11.30號單日監控資料,發現雙端同時存在Http2.0、Http1.1兩種協議版本的請求,因此從Http一些版本的維度進行監控資料分析。

檢視雙端Http2.0與Http1.1佔比

iOS:Http2.0佔比51.98%,Http1.1佔比48.01%

Android:Http2.0佔比76.46%,Http1.1佔比23.53%

可以看到雙端都存在20%以上的Http1.1流量。

檢視雙端Http2.0與Http1.1各自的TCP複用率

iOS:Http2.0 TCP複用率9217%,Http1.1 TCP複用率396%

Android:Http2.0 TCP複用率2397%,Http1.1 TCP複用率681%

發現雙端Http2.0的TCP複用率比Http1.1的TCP複用率高出幾倍, iOS 端差不多高一個量級

注:TCP複用率 = TCP連線複用次數 / TCP建連成功次數

由於TCP每次重新建連都需要經過DNS解析、TCP三次握手、SSL四次握手階段的耗時,而TCP連線複用時則節省了這三個階段的耗時,複用TCP連線的CDN資源請求耗時更短。也就是說TCP複用率越高,CDN資源請求的平均耗時越短。

講到這裡,可能很多同學就提出了疑問,為什麼Http2.0的TCP複用率可以達到這麼高呢?下面我們簡單介紹下Http2.0協議。

3.4.2 什麼是Http2.0協議

Http2.0有哪些優勢?相比Http1.1的區別是什麼?

Http1.1協議仍是使用最廣泛的Http協議,但其存在的痛點也眾所周知,包括:

1.請求擁塞:併發的每個請求都需要一個TCP連線,並且最多6個,超過則會擁塞等待;

2.頭部冗餘:不支援頭部壓縮,且每次請求都會重複傳遞頭部,造成頻寬浪費並影響效能;

3.單向傳輸:僅支援客戶端向服務端傳送,不支援服務端主動向客戶端傳送;

4.明文傳輸:支援Http方式請求,資料明文傳輸,存在安全風險;

5.優先順序受限:同一個TCP連線上僅支援序列傳送,不支援高優先順序請求率先傳送,影響效能。

Http2.0協議是對http1.1協議的擴充和優化,引入了幀的概念,在應用層與傳輸層之間新增了二進位制分幀層,針對性的提出了幾點新特性:

1.多路複用:解決Http1.1請求擁塞的痛點,併發的多個請求支援在同一個TCP連線上進行傳輸,每個請求都會被拆分成一個個的幀,幀頭資訊會儲存對應的請求資訊,以二進位制形式傳輸到對端後會根據幀頭資訊將請求資料進行重組;

2.頭部壓縮:解決Http1.1頭部冗餘的痛點,一方面使用HPACK演算法對頭部進行壓縮減小傳輸體積,另一方面在雙端維護Headers表,對已傳輸過的頭部僅需攜帶對應key,避免重複傳輸;

3.服務端推送:解決Http1.1單向傳輸的痛點,允許服務端向客戶端主動推送資料,如html請求時,服務端會主動向客戶端推送相關的css,js檔案,避免客戶端多次請求,降低整體RT耗時;

4.二進位制傳輸:解決Http1.1明文傳輸的痛點,資料被封裝成幀,幀再以二進位制形式進行傳輸;

5.支援優先順序:解決Http1.1優先順序受限的痛點,新建的流使用報文幀設定優先順序,已建立的流使用優先順序幀型別設定優先順序,在資源有限的情況下使用優先順序選擇Stream流進行傳輸;

友商使用Http2.0情況調研

調研友商的CDN資源請求Http協議版本,友商App都使用的Http2.0協議,驗證了Http2.0協議的可行性。

與TLS1.3協議友商調研方法類似,通過Chrome瀏覽器載入友商的圖片,在DevTools視窗的Network皮膚可以看到使用的是h2協議。

3.4.3 Http2.0升級優化方案

對CDN域名cdn.poizon.com Http1.1協議版本請求的CDN邊緣節點的IP分析後發現非阿里雲CDN,與運維同學確認後得知CDN域名cdn.poizon.com切了40%流量在七牛雲CDN,使用的Http1.1協議。

可以採用將這部分七牛雲的流量進行Http2.0升級來提升CDN資源請求效能,執行線上變更將流量切回阿里雲CDN(已開啟Http2.0協議)。

3.4.4 Http2.0升級優化效果

CDN域名cdn.poizon.com流量切回阿里雲後,https1.1流量已轉為https2.0,https2.0流量佔比雙端均95%+,優化前後資料:

平均耗時

  1. iOS 248ms -> 221ms,降低27ms
  2. Android 350ms -> 329ms,降低21ms

TCP複用率

  1. iOS:841% -> 5127%,升高4286%

  1. Android:1441% -> 2160%,升高719%

4.小結

以上4個優化方向可以讓你以較少的人力投入獲得比較顯著的CDN資源請求效能提升,但因涉及到線上變更,要注意做好線下回歸測試,線上變更、驗證、監控、還原方案。

最後,感謝運維,測試及相關參與同學在CDN資源請求優化過程中的協助。

文/Aix

關注得物技術,做最潮技術人!

相關文章