bang 移動 APP 網路優化概述

2021-08-15 10:37:27 字數 4304 閱讀 4085

速度:網路請求的速度怎樣能進一步提公升?

弱網:移動端網路環境隨時變化,經常出現網路連線很不穩定可用性差的情況,怎樣在這種情況下最大限度最快地成功請求?

安全:怎樣防止被第三方竊聽/篡改或冒充,防止運營商劫持,同時又不影響效能?

正常一條網路請求需要經過的流程是這樣:

dns 解析,請求dns伺服器,獲取網域名稱對應的 ip 位址。

與服務端建立連線,包括 tcp 三次握手,安全協議同步流程。

連線建立完成,傳送和接收資料,解碼資料。

這裡有明顯的三個優化點:

直接使用 ip 位址,去除 dns 解析步驟。

不要每次請求都重新建立連線,復用連線或一直使用同一條連線(長連線)。

壓縮資料,減小傳輸的資料大小。

逐條來看能做什麼。

dns 完整的解析流程很長,會先從本地系統快取取,若沒有就到最近的 dns 伺服器取,若沒有再到主網域名稱伺服器取,每一層都有快取,但為了網域名稱解析的實時性,每一層快取都有過期時間,這種 dns 解析機制有幾個缺點:

快取時間設定得長,網域名稱更新不及時,設定得短,大量 dns 解析請求影響請求速度。

網域名稱劫持,容易被中間人攻擊,或被運營商劫持,把網域名稱解析到第三方 ip 位址,據統計劫持率會達到7%。

dns 解析過程不受控制,無法保證解析到最快的ip

一次請求只能解析乙個網域名稱。

為了解決這些問題,就有了 httpdns,原理很簡單,就是自己做網域名稱解析的工作,通過 http 請求後台去拿到網域名稱對應的 ip 位址,直接解決上述所有問題:

通過簽名等方式,保證 httpdns 請求的安全,避免被劫持。

dns 解析由自己控制,可以確保根據使用者所在地返回就近的 ip 位址,或根據客戶端測速結果使用速度最快的 ip。

一次請求可以解析多個網域名稱。

第二個問題,連線建立耗時的問題,這裡主要的優化思路是復用連線,不用每次請求都重新建立連線,如何更有效率地復用連線,可以說是網路請求速度優化裡最主要的點了,並且這裡的優化仍在演進過程中,值得了解下。

keep-alive

http 協議裡有個 keep-alive,http1.1預設開啟,一定程度上緩解了每次請求都要進行tcp三次握手建立連線的耗時。原理是請求完成後不立即釋放連線,而是放入連線池中,若這時有另乙個請求要發出,請求的網域名稱和埠是一樣的,就直接拿出連線池中的連線進行傳送和接收資料,少了建立連線的耗時。

實際上現在無論是客戶端還是瀏覽器都預設開啟了keep-alive,對同個網域名稱不會再有每發乙個請求就進行一次建連的情況,純短連線已經不存在了。但有個問題,就是這個 keep-alive 的連線一次只能傳送接收乙個請求,在上乙個請求處理完成之前,無法接受新的請求。若同時發起多個請求,就有兩種情況:

若序列傳送請求,可以一直復用乙個連線,但速度很慢,每個請求都要等待上個請求完成再進行傳送。

若並行傳送這些請求,那麼首次每個請求都要進行tcp三次握手建立新的連線,雖然第二次可以復用連線池裡這堆連線,但若連線池裡保持的連線過多,對服務端資源產生較大浪費,若限制了保持的連線數,並行請求裡超出的連線仍每次要建連。

對這個問題,新一代協議 http2 提出了多路復用去解決。

多路復用

http2 的多路復用機制一樣是復用連線,但它復用的這條連線支援同時處理多條請求,所有請求都可以併發在這條連線上進行,也就解決了上面說的併發請求需要建立多條連線帶來的問題,網路上有張圖可以較形象地表現這個過程:

替換下原文的圖,知乎的圖我覺得更好一些:

http1.1的協議裡,在乙個連線裡傳送資料都是序列順序傳送的,必須等上乙個請求全部處理完後,下乙個請求才能進行處理,導致這些請求期間這條連線並不是滿頻寬傳輸的,即使是http1.1的pipelining可以同時傳送多個request,但response仍是按請求的順序序列返回,只要其中乙個請求的response稍微大一點或發生錯誤,就會阻塞住後面的請求。

http2 這裡的多路復用協議解決了這些問題,它把在連線裡傳輸的資料都封裝成乙個個stream,每個stream都有標識,stream的傳送和接收可以是亂序的,不依賴順序,也就不會有阻塞的問題,接收端可以根據stream的標識去區分屬於哪個請求,再進行資料拼接,得到最終資料。

解釋下多路復用這個詞,多路可以認為是多個連線,多個操作,復用就是字面上的意思,復用一條連線或乙個執行緒。http2這裡是連線的多路復用,網路相關的還有乙個i/o的多路復用(select/epoll),指通過事件驅動的方式讓多個網路請求返回的資料在同一條執行緒裡完成讀寫。

tcp隊頭阻塞

http2 的多路復用看起來是完美的解決方案,但還有個問題,就是隊頭阻塞,這是受限於 tcp 協議,tcp 協議為了保證資料的可靠性,若傳輸過程中乙個 tcp 包丟失,會等待這個包重傳後,才會處理後續的包。http2的多路復用讓所有請求都在同一條連線進行,中間有乙個包丟失,就會阻塞等待重傳,所有請求也就被阻塞了。

對於這個問題不改變 tcp 協議就無法優化,但 tcp 協議依賴作業系統實現以及部分硬體的定製,改進緩慢,於是 google 提出 quic 協議,相當於在 udp 協議之上再定義一套可靠傳輸協議,解決 tcp 的一些缺陷,包括隊頭阻塞。具體解決原理網上資料較多,可以看看。

quic 處於起步階段,少有客戶端接入,quic 協議相對於 http2 最大的優勢是對tcp隊頭阻塞的解決,其他的像安全握手 0rtt / 證書壓縮等優化 tls1.3 已跟進,可以用於 http2,並不是獨有特性。tcp 隊頭阻塞在 http2 上對效能的影響有多大,在速度上 quic 能帶來多大提公升待研究。

第三個問題,傳輸資料大小的問題。資料對請求速度的影響分兩方面,一是壓縮率,二是解壓序列化反序列化的速度。目前最流行的兩種資料格式是 json 和 protobuf,json 是字串,protobuf 是二進位制,即使用各種壓縮演算法壓縮後,protobuf 仍會比 json 小,資料量上 protobuf 有優勢,序列化速度 protobuf 也有一些優勢,這兩者的對比就不細說了。

壓縮演算法多種多樣,也在不斷演進,最新出的 brotli 和z-standard實現了更高的壓縮率,z-standard 可以根據業務資料樣本訓練出適合的字典,進一步提高壓縮率,目前壓縮率表現最好的演算法。

除了傳輸的 body 資料,每個請求 http 協議頭的資料也是不可忽視,http2 裡對 http 協議頭也進行了壓縮,http 頭大多是重複資料,固定的字段如 method 可以用靜態字典,不固定但多個請求重複的字段例如 cookie 用動態字典,可以達到非常高的壓縮率,這裡有詳細介紹。

通過 httpdns,連線多路復用,更好的資料壓縮演算法,可以把網路請求的速度優化到較不錯的程度了,接下來再看看弱網和安全上可以做的事情。

提公升連線成功率

復合連線,建立連線時,階梯式併發連線,其中一條連通後其他連線都關閉。這個方案結合序列和併發的優勢,提高弱網下的連線成功率,同時又不會增加伺服器資源消耗:

制定最合適的超時時間

對總讀寫超時(從請求到響應的超時)、首包超時、包包超時(兩個資料段之間的超時)時間制定不同的計算方案,加快對超時的判斷,減少等待時間,盡早重試。這裡的超時時間還可以根據網路狀態動態設定。

調優tcp引數,使用tcp優化演算法。

對服務端的tcp協議引數進行調優,以及開啟各種優化演算法,使得適合業務特性和移動端網路環境,包括rto初始值,混合慢啟動,tlp,f-rto等。

標準協議 tls 保證了網路傳輸的安全,前身是 ssl,不斷在演進,目前最新是 tls1.3。常見的 https 就是 http 協議加上 tls 安全協議。

安全協議概括性地說解決兩個問題:1.保證安全 2. 降低加密成本

在保證安全上:

使用加密演算法組合對傳輸資料加密,避免被竊聽和篡改。

認證對方身份,避免被第三方冒充。

加密演算法保持靈活可更新,防止定死演算法被破解後無法更換,禁用已被破解的演算法。

降低加密成本上:

用對稱加密演算法加密傳輸資料,解決非對稱加密演算法的效能低以及長度限制問題。

快取安全協議握手後的金鑰等資料,加快第二次建連的速度。

加快握手過程:2rtt-> 0rtt。加快握手的思路,就是原本客戶端和服務端需要協商使用什麼演算法後才能加密傳送資料,變成通過內建的公鑰和預設的演算法,在握手的同時就把資料發出去,也就是不需要等待握手就開始傳送資料,達到0rtt。

這些點涉及的細節非常多,對 tls 的介紹有一篇雄文,說得很詳細,在此推薦。

網路優化這個話題非常龐大,本文只是在學習過程中從優化思路上列舉了目前業界常見的優化點,還有很多細節很多更深入的優化沒涉及到,網路層實踐開發經驗不足,若有錯誤歡迎指出。

***********************學習筆記***********************

移動 APP 網路優化概述

速度 網路請求的速度怎樣能進一步提公升?弱網 移動端網路環境隨時變化,經常出現網路連線很不穩定可用性差的情況,怎樣在這種情況下最大限度最快地成功請求?安全 怎樣防止被第三方竊聽 篡改或冒充,防止運營商劫持,同時又不影響效能?正常一條網路請求需要經過的流程是這樣 dns 解析,請求dns伺服器,獲取網...

移動App網路優化

本篇文章是對bang神的文章 進行的總結,文章中也加了的一些 自己的理解與擴充套件。我們每次在做業務做網路請求的時候,想必每個人都思考過如何進一步優化網路請求吧,比如這三點包括 正常一條網路請求需要經過的流程是這樣 這裡有明顯的三個優化點 依次來分析每個優化點我們能做什麼 1 dns dns 完整的...

移動app傳統測試流程優化

本文出自天外歸雲的 在傳統的軟體測試流程中,每一期需求從開發到上線都要經歷從需求分析與評審 測試用例評審 開發 測試 發布的流程。其中測試包含了後台測試 前端web測試 客戶端測試。後台測試又包括後台 邏輯測試 介面測試 介面壓力測試等,web端測試包含了前端頁面的ui介面測試 pc與移動端瀏覽器相...