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 優化前後資料:
平均耗時
- iOS:429ms -> 331ms,降低98ms
- 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耗時均有明顯降低,優化前後資料:
平均耗時
- iOS:281ms -> 237ms,降低44ms
- Android:307ms -> 269ms,降低38ms
SSL階段耗時
- iOS:210ms -> 137ms,降低73ms
- 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%+,優化前後資料:
平均耗時
- iOS 248ms -> 221ms,降低27ms
- Android 350ms -> 329ms,降低21ms
TCP複用率
- iOS:841% -> 5127%,升高4286%
- Android:1441% -> 2160%,升高719%
4.小結
以上4個優化方向可以讓你以較少的人力投入獲得比較顯著的CDN資源請求效能提升,但因涉及到線上變更,要注意做好線下回歸測試,線上變更、驗證、監控、還原方案。
最後,感謝運維,測試及相關參與同學在CDN資源請求優化過程中的協助。
文/Aix
關注得物技術,做最潮技術人!