【iOS】iOS網(wǎng)絡(luò)優(yōu)化方案

1、DNS映射

無論是HTTP還是Socket長連接,第一步都要經(jīng)過DNS解析出ip,然后再根據(jù)ip去拿對應(yīng)的資源。在這個過程中,如果LocalDNS中存在這個域名對應(yīng)的ip,就會直接返回這個ip,類似于App內(nèi)做的緩存。如果不存在,才會去權(quán)威DNS查詢該訪問哪個ip,然后查詢到的ip會在LocalDNS中做緩存。然而在iOS設(shè)備上幾乎每次斷網(wǎng)重連,重啟設(shè)備都會使LocalDNS緩存失效,觸發(fā)重新查詢。
同時,LocalDNS緩存的存在還會引發(fā)一些問題。如果之前訪問api.weibo.cn的是聯(lián)通用戶,現(xiàn)在新用戶使用電信來訪問api.weibo.cn,由于localDNS緩存的存在,不會去查詢新浪的權(quán)威DNS,這樣返回的ip是聯(lián)通這個運(yùn)營商的ip,從而會使得用戶出現(xiàn)訪問變慢等狀況。
緩存還會導(dǎo)致一點(diǎn)就是,當(dāng)權(quán)威DNS將域名與ip的映射發(fā)生改變之后,由于LocalDNS緩存沒有及時改變,用戶就會訪問到錯誤的服務(wù)器,或者直接訪問不到資源。還有很多三四級運(yùn)營商會把域名解析指向他們的緩存服務(wù)器上,并把網(wǎng)頁里面的廣告替換成他們自己的,或者內(nèi)嵌他們自己的廣告。
HttpDNS基于Http協(xié)議和域名解析的流量調(diào)度解決方案,可以在很大程度上防止上面的問題出現(xiàn)。

HttpDNS原理:

A、客戶端直接訪問HttpDNS接口,獲取業(yè)務(wù)在域名配置管理系統(tǒng)上配置的訪問延遲最優(yōu)的IP。(基于容錯考慮,app內(nèi)肯定是需要保留使用運(yùn)營商LocalDNS解析域名方式的。)
B、客戶端獲取到IP后就直接往此IP發(fā)送業(yè)務(wù)協(xié)議請求。以Http請求為例,通過在header中指定host字段,向HttpDNS返回的IP發(fā)送標(biāo)準(zhǔn)的Http請求即可。

基于HttpDNS擴(kuò)展:

A、在App內(nèi)維護(hù)一個Serve IP List。把每次App從HttpDNS取到的ip存儲進(jìn)入該數(shù)組,并設(shè)置權(quán)重,理論上來說從HttpDns解析下來的ip權(quán)重是最大的。這個List可以在App啟動的時候,進(jìn)行更新,同時取出本地緩存的Serve IP List的權(quán)重最大的ip進(jìn)行數(shù)據(jù)的初始化操作(如果第一次啟動,沒有該List的話,就使用LocalDNS進(jìn)行解析)。Serve IP List里面的權(quán)重設(shè)置機(jī)制,很明顯的一點(diǎn)就是從DNS解析出來的ip具有最大的權(quán)重,每次從List里面取ip應(yīng)該要取權(quán)重最大的ip。列表中的ip也是需要可以動態(tài)更新配置的,根據(jù)連接或者服務(wù)的成功失敗來進(jìn)行動態(tài)調(diào)整,這樣即使DNS解析失敗,用戶在一段時間后也會取到合適的ip進(jìn)行訪問。
B、對ip進(jìn)行數(shù)據(jù)統(tǒng)計(jì)。在所有app內(nèi)統(tǒng)計(jì)每個ip進(jìn)行請求所需平均時間、最長時間、最短時間、請求成功次數(shù)、失敗次數(shù),需要注意的是,要區(qū)分網(wǎng)絡(luò)環(huán)境進(jìn)行統(tǒng)計(jì),Wifi、4G、3G,對在不同的網(wǎng)絡(luò)環(huán)境下數(shù)據(jù)優(yōu)秀的ip進(jìn)行存儲,下發(fā)到App里面使用起來。這樣每次啟動App時可以對收集起來的ip根據(jù)不同的網(wǎng)絡(luò)環(huán)境進(jìn)行測速,選擇最好的ip進(jìn)行請求。需要注意的是,在網(wǎng)絡(luò)環(huán)境切換的時候,必須要重新進(jìn)行速度測試。做到這一步,可以節(jié)約DNS解析時間,以及劫持的問題。
C、將圖片、音頻等資源放到單獨(dú)的服務(wù)器里面,與其他資源分開。第一個是多個域名可以增加并行下載條數(shù),因?yàn)榭蛻舳藢ν粋€域的域名下載條數(shù)是有限制的,所以多個域就會增加并行下載條數(shù),從而加快加載速度。當(dāng)然二級域名也不能使用太多,因?yàn)樘嘁紤]到dns的解析花費(fèi)的時間。第二個是方便管理,一般來說,圖片在站點(diǎn)的加載中是最占帶寬的,可以用獨(dú)立服務(wù)器方便后期管理;還可以使用異步加載的方式,增強(qiáng)用戶體驗(yàn)。同時是圖片多是靜態(tài)內(nèi)容,可以更好的使用CDN加速。第三是如果使用了獨(dú)立服務(wù)器的話,在安全設(shè)置上可以有差別的針對設(shè)置,很是方便。
D、在防止劫持這一塊,需要注意把資源的后綴名去掉,比如說.mp3、.json這樣的后綴,以免擊中運(yùn)營商的攔截。

總的來說,采用HttpDNS來解析域名,就繞過了三四級運(yùn)營商解析域名會出現(xiàn)的問題,在HttpDNS返回了正確的ip之后,我們是直接采用ip去進(jìn)行http請求,只需要關(guān)注通信內(nèi)容的安全即可。

2、資源優(yōu)化

資源優(yōu)化基本就是盡可能的縮小傳輸數(shù)據(jù)的大小,選擇合適的數(shù)據(jù)格式。
1、首先是圖片大小的解決方案,在一定程度上使用webp來代替jpg、png圖片,各種圖片同等質(zhì)量下的大小,webp是最小的。
2、可以使用ProtocolBuffer代替Json進(jìn)行數(shù)據(jù)傳輸,因?yàn)镻rotocolBuffer數(shù)據(jù)比Json更小,也是跨平臺的,序列化與反序列化也很簡單。

3、請求壓縮

DNS查詢之后是TCP握手建立連接,并發(fā)送請求數(shù)據(jù)。對于TCP來說,單個IP包大小受限于MSS值,大部分用戶所處網(wǎng)絡(luò)環(huán)境下每個包的大小約在1.5KB,新建立的HTTP連接由于TCP的slow start特性,會導(dǎo)致本地的部分IP包被臨時緩存,從而增加了整體request的延遲。所以我們應(yīng)該盡可能嘗試去壓縮我們的網(wǎng)絡(luò)請求業(yè)務(wù)數(shù)據(jù),減少一個Request的IP包數(shù)量,或許可以讓用戶少經(jīng)歷一個RTT,降低請求延遲的用戶感知。

4、請求合并

對于非關(guān)鍵性的業(yè)務(wù)數(shù)據(jù),或者對實(shí)時性要求不高的請求來說,通過合并請求的方式可以減少和服務(wù)器交互的次數(shù),一則降低服務(wù)器壓力,二則合并之后再壓縮能節(jié)約客戶端的流量。這類請求一般見于打點(diǎn)SDK,crash日志收集等非業(yè)務(wù)型請求。

5、請求的安全性

盡量使用HTTPS來保證基本的網(wǎng)絡(luò)安全。對于敏感數(shù)據(jù),采用MD5、AES、DES、RSA等加密方式來保證數(shù)據(jù)的安全傳輸,防止被攔截及篡改。

6、合理的并發(fā)數(shù)

有些業(yè)務(wù)場景會出現(xiàn)多個Request集中產(chǎn)生的情況,此時我們需要設(shè)置一個合理的并發(fā)數(shù)。并發(fā)數(shù)如果太小,會導(dǎo)致“劣質(zhì)”的請求block住“優(yōu)質(zhì)”的請求。如果并發(fā)數(shù)太大,帶寬有限的場景下,會增加請求的整體延遲。

7、數(shù)據(jù)緩存

1、使用HTTP緩存,減少請求次數(shù),減小傳輸量(能不傳body就不傳)HTTP網(wǎng)絡(luò)緩存減少了需要向服務(wù)器發(fā)送請求的次數(shù)。當(dāng)一個請求完成下載來自服務(wù)器的回應(yīng),一個緩存的回應(yīng)將在本地保存。下一次同一個請求再發(fā)起時,本地保存的回應(yīng)就會馬上返回,不需要連接服務(wù)器。NSURLCache就干這個,既可以緩存在Memory,又可以緩存在Disk上。
2、將Html,JS,CSS等網(wǎng)頁靜態(tài)文件存在手機(jī)上,標(biāo)記版本,建立合適的更新機(jī)制。利用NSURLProtocol做網(wǎng)頁的緩存(第一次),將網(wǎng)絡(luò)IO改變?yōu)楸镜豂O,提高H5體驗(yàn)。

8、可靠性保障

可靠性保障也是個容易被忽視的方面,在深入探討之前,可以先將Request按業(yè)務(wù)屬性分類。

  • 第一類:關(guān)鍵核心的業(yè)務(wù)數(shù)據(jù),期望能100%送達(dá)服務(wù)器。
  • 第二類:重要內(nèi)容請求,需要較高的請求成功率。
  • 第三類:一般性內(nèi)容請求,對成功率無要求。

之所以要將請求分為三類,是要在可靠性保障上做區(qū)分。理論上我們應(yīng)該盡可能讓所有的請求成功率達(dá)到最高,但客戶端的流量,帶寬,手機(jī)電量,服務(wù)器的壓力等都是有限的資源,所以我們采取的策略是只對關(guān)鍵性的網(wǎng)絡(luò)請求做高強(qiáng)度的可靠性保障。
第一類請求類似大家用微信時發(fā)送的消息,消息數(shù)據(jù)一旦從輸入框發(fā)出,從用戶來的角度感知這個消息數(shù)據(jù)是一定會到達(dá)對方的。如果網(wǎng)絡(luò)環(huán)境差,網(wǎng)絡(luò)模塊會自動在后頭悄悄重試,一段時間后仍無法成功就通過產(chǎn)品交互的方式告知用戶發(fā)送失敗了,即使失敗,請求的數(shù)據(jù)(消息本身)一直存在客戶端。
對于這類請求的處理方式,第一步不是通過網(wǎng)絡(luò)發(fā)送,而是先將請求持久化到DB當(dāng)中。一旦入了DB,即使斷網(wǎng),斷電,重啟,請求數(shù)據(jù)依然還在,只需在App重啟的時候還原請求數(shù)據(jù),再次發(fā)送即可。第二步發(fā)送請求,如果請求失敗則將請求加入重試隊(duì)列,成功則從重試隊(duì)列中移除。重試隊(duì)列背后也需要一套通用機(jī)制,比如多久重試一次,重試幾次之后放棄。遇到最惡劣的場景,請求發(fā)送失敗之后,App被kill。我們需要在App重啟之后從DB當(dāng)中重新load所有失敗的請求再次重試。
如果判斷為第一類請求,通過上述幾步基本上可以使請求的可靠性得到極大的保障,但100%是很難實(shí)現(xiàn)的。如果請求失敗的時候用戶重裝App,所有持久化的數(shù)據(jù)丟失,請求數(shù)據(jù)也就丟了,不過這種極端的場景非常少。
第二類請求的例子可以是我們App啟動時用戶看到的首頁,首頁的內(nèi)容從服務(wù)器獲取,如果第一次請求就失敗體驗(yàn)較差,這種場景下我們應(yīng)該允許請求有機(jī)會多試幾次,增加一個retryCount即可。一般3次的重試基本可以排除網(wǎng)絡(luò)抖動的情況。三次失敗之后即可認(rèn)為請求失敗,通過產(chǎn)品交互告知用戶。
第三類請求的重要性最低,比如進(jìn)入Controller的UV采集打點(diǎn)。這類請求只需要做一次,即使失敗也不會對產(chǎn)品體驗(yàn)產(chǎn)生什么負(fù)面影響。

9、多通道

現(xiàn)在不少有技術(shù)條件的團(tuán)隊(duì)都有自己的tcp長連接通道,技術(shù)再硬點(diǎn)的甚至配有UDP通道,UDP在丟包率高的網(wǎng)絡(luò)環(huán)境下能極大的提高請求成功的概率。如果能同時具備HTTP,TCP,UDP三條網(wǎng)絡(luò)通道,在某些場景下,如果不考慮流量(比如wifi),可以針對某個網(wǎng)絡(luò)請求,兩通道或者三通道齊發(fā),對請求成功的速度和可靠性有明顯的療效,不過客戶端和服務(wù)器都需要針對業(yè)務(wù)場景做去重。UDP在VOIP服務(wù)當(dāng)中使用較多,不過據(jù)說淘寶這類大廠也部分啟用了UDP。

10、網(wǎng)絡(luò)環(huán)境監(jiān)控

現(xiàn)在網(wǎng)絡(luò)環(huán)境雖然越來越好,Wifi,4G,3G在一二線城市都有很好的普及,但還是有不少場景會導(dǎo)致網(wǎng)絡(luò)狀態(tài)突然變差,比如進(jìn)電梯,坐火車,人多的集會場所,從公司回家4G切Wifi等等,這些場景在生活當(dāng)中并不少見,健壯的網(wǎng)絡(luò)模塊需要仔細(xì)的檢測網(wǎng)絡(luò)的變化,針對性的做請求重試。

11、請求成功率監(jiān)控

網(wǎng)絡(luò)模塊應(yīng)該能監(jiān)控當(dāng)前App的網(wǎng)絡(luò)請求成功率,對于失敗率較高的請求,帶上業(yè)務(wù)數(shù)據(jù),手機(jī)網(wǎng)絡(luò)環(huán)境,系統(tǒng)參數(shù)等等,在用戶不活躍的時候能打包上報(bào)給server端,一則能找出更多需要優(yōu)化的業(yè)務(wù)場景,二則能實(shí)時監(jiān)控server端的健康狀態(tài),三則能從數(shù)據(jù)層面精確判斷每一次網(wǎng)絡(luò)優(yōu)化是否有成效。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容