1、背景css
如何度量和模擬「弱網絡」對移動APP的開發有着重大的意義,好比:節約測試成本、易於問題重現、加快產品上線等。html
通常的方法是使用「丟包率」和「網絡延時」來定義和衡量「弱網絡」。web
2、手機接入服務器的流程算法
要講這個問題,首先要來了解下手機接入服務器的流程。gulp
- 首先,手機要經過無線網絡協議,從基站得到無線鏈路分配,才能跟網絡進行通信。
- 無線網絡基站、基站控制器這方面,會給手機進行信號的分配,已完成手機鏈接和交互。
- 得到無線鏈路後,會進行網絡附着、加密、鑑權,核心網絡會檢查你是否是能夠鏈接在這個網絡上,是否開通套餐,是否是漫遊等。核心網絡有SGSN和GGSN,在這一步完成無線網絡協議和有線以太網的協議轉換。
- 再下一步,核心網絡會給你進行APN選擇、IP分配、啓動計費。
- 再往下面,纔是傳統網絡的步驟:DNS查詢、響應,創建TCP連接,HTTP GET,RTTP RESPONSE 200 OK,HTTP RESPONSE DATA,LAST HTTP RESPONSE DATA,開始UI展示。
這是手機經過無線網絡接入服務器的全過程。整個過程中有幾個困擾開發者的問題:緩存
無線網絡是怎麼給手機分配到無線鏈路的?服務器
核心網絡有接入點(APN),這裏的CMNET和CMWAP有什麼區別,僅僅是協議不一樣嗎嗎?數據轉發又有什麼區別?一個數據包在不一樣網絡上傳輸有不一樣嗎?網絡
用戶怎麼最快的找到正確的服務器?內容怎麼快速有效的加載,在第一時間顯示出來?架構
這幾個問題的重點在於其中的幾個鏈接點:併發
- 無線鏈路分配。這是一個物理實鏈接。
- IP層連接。這是一個邏輯虛鏈接。
- TCP層連接。這是一個邏輯虛鏈接。
- HTTP層連接。這是一個邏輯虛鏈接。
- 用戶在線。這是一個邏輯虛鏈接。
3.2 一秒鐘法則
根據以上狀況,就造成無線網絡的一大特色:秒級狀態管理,秒級狀態轉換。這兩個操做都在幾百ms到幾秒之間進行,對於維持鏈接來講時間過短,對於從無鏈接到有鏈接的轉換來講時間又太長。
相比之下,有線網絡的狀態管理如ip分配、tcp鏈接釋放,都是分鐘級,而狀態轉換則是毫秒級。
這些通信機制,同時加上無線網絡的高延遲、高丟包。如何保證移動互聯網的產品提供穩定的、可預期的服務質量,成爲很是大的挑戰:
2G網絡上無線部分數據傳輸的延遲有幾百ms,4G網絡上無線部分傳輸延遲減小到幾十ms,核心網狀態轉換、協議轉換30~100ms,IP骨幹網上的延遲又跟物理距離以及運營商互聯互通質量有關,跨運營商50-400ms,同運營商5-80ms,這個還要取決於網絡擁塞的狀況。
無線網絡誤碼率比有線高兩個數量級,在不一樣時間段的波動也很是巨大。
怎麼基於移動網絡的特性去優化服務?
這就是咱們總結的一秒鐘法則:在一秒內要完成的規定動做。
- 2g網絡:1秒內完成dns查詢、和後臺服務器創建鏈接
- 3g網絡:1秒內完成首字顯示(首字時間)
- wifi網絡:1秒內完成首屏顯示(首屏時間)
- 這些指標須要在終端度量,必須跟用戶體驗相關:首字時間、首屏時間都必須是用戶能夠直觀感覺到的。
4、優化思路
4.1 服務保證原則
從以上分析可知,如何保證移動互聯網的產品提供穩定的、可預期的服務質量,具備很是大的挑戰。如下幾點原則可能會有幫助:
- 接口設計優化,接口的優化理論上不屬於APP弱網絡的優化,可是這個的API性能的問題,確實在網絡條件很差的狀況下才暴露無遺。你們都在談論服務器的好壞,設備的性能高低,其實,對於一個良好的Server來講,絕大部分拖延請求速度的地方都是在IO上。包括,磁盤讀寫的IO,SQL查詢的IO等等。經常使用的優化點:慢查詢監控 、屢次查詢優化、經常使用接口cache等。
- 圖片相關策略。
- 使用更快的圖片格式,嚴格說也不算弱網下的優化,但一個更快的圖片格式真的很重要!這裏建議採用WebP格式。(WebP格式,谷歌(google)開發的一種旨在加快圖片加載速度的圖片格式。圖片壓縮體積大約只有JPEG的2/3,並能節省大量的服務器帶寬資源和數據空間。但WebP是一種有損壓縮。相較編碼JPEG文件,編碼一樣質量的WebP文件須要佔用更多的計算資源。)
- 不一樣網絡的不一樣圖片下發。如(對於原圖是600X480的圖片):2/3G使用低清晰度圖片——>下發300X240,精度爲80的圖片、4G普通清晰度圖片——>下發600X480,精度爲80的圖片、WiFi高清晰度圖片(最好根據網速來判斷,wifi也有慢的)——>下發600X480,精度爲100的圖片。
- 斷線重連。這多是最重的一個特性,由於在無線網絡中有太多的緣由致使數據鏈接中斷了。這裏可使用CDN。(CDN 是構建在數據網絡上的一種分佈式的內容分發網。 CDN 的做用是採用流媒體服務器集羣技術,克服單機系統輸出帶寬及併發能力不足的缺點,可極大提高系統支持的併發流數目,減小或避免單點失效帶來的不良影響。)
- 因爲建立鏈接是一個很是昂貴的操做,因此應儘可能減小數據鏈接的建立次數,且在一次請求中應儘可能以批量的方式執行任務。若是屢次發送小數據包,應該儘可能保證在2秒之內發送出去。在短期內訪問不一樣服務器時,儘量地複用無線鏈接。
- 優化DNS查詢。應儘可能減小DNS查詢、避免域名劫持、DNS污染,同時把用戶調度到「最優接入點」。
- 減少數據包大小和優化包量。經過壓縮、精簡包頭、消息合併等方式,來減少數據包大小和包量。
- 控制數據包大小不超過1500,避免分片。包括邏輯鏈路控制(Logic Link Control)分片、GGSN分片,以及IP分片。其中,當數據包大小超出GGSN所容許的最大大小時,GGSN的處理方式有如下三種:分片、丟棄和拒絕。
- 優化TCP socket參數,包括:是否關閉快速回收、初始RTO、初始擁塞窗口、socket緩存大小、Delay-ACK、Selective-ACK、TCP_CORK、擁塞算法(westwood/TLP/cubic)等。作這件事情的意義在於:因爲2G/3G/4G/WIFI/公司內網等接入網絡的QoS差別很大,因此不一樣網絡下爲了取得較好的服務質量,上述參數的取值差別可能會很大。
- 優化ACK包。在弱網絡的狀況下,TCP協議中的ACK包是很是昂貴的,延時甚至可以達到秒級別,而TCP協議的擁塞控制、快速重傳、快速恢復等特性都很是依賴接收端反饋的ACK包。可想而知,若是發送端接收到的ACK包延時太長,會嚴重影響TCP協議的效率。可是若是發送ACK太多又會佔用寶貴過多的無線資源。在移動網絡下通訊,「在可靠的鏈接上,如何在減小ACK包的狀況下,下降數據包的延時」是研究的熱點。基本的思想:平衡冗餘包和ACK包個數,達到下降延時,提升吞吐量的目的。例如SGSN和GGSN之間的通訊實現:兩者之間經過UDP協議通訊,發送者在無新的數據包的狀況下,每隔必定的時間重試已發送的包,達到最大重試次數後,則丟棄該包。
- TCP的擁塞控制算法是以「丟包意味着網絡出現擁塞」爲假設設計的,很明顯這個假設在無線網絡環境下是不合適的。可是在無線網絡環境下,在設計可靠UDP協議時是否可以徹底丟棄擁塞控制呢?這裏有其它的文章中提出了幾種在無線網絡環境下的TCP友好的擁塞控制算法,有興趣能夠自行查閱。
- 靈活使用長鏈接/短鏈接,支持不一樣協議(TCP/UDP, http、二進制協議等),支持不一樣端口等。
- 讓用戶以爲快。到這裏已經不能算是技術層面的方法了,屬於一種心理層面的博弈,一種改善用戶體驗的方式。好比:
- 不從0開始的進度條。無論網頁的加載進度如何,無論網絡條件如何,加載進度始終是從50%起,而且停留在大約98%進度左右的地方。
- 先顯示文字在加載圖片。一樣是在Webview之中,圖片或者多媒體的加載速度確定是遠遠慢過文字的加載速度的。因爲不一樣的webview顯示和渲染效果不一樣,咱們能夠先讓webview先顯示文字,在顯示圖片。給用戶一種能夠先預覽整個網頁概況的感受。
4.2 接入調度優化
接入調度優化首先要考慮的是減小DNS的影響。移動網絡的DNS有以下特色:
- 骨幹網沒法識別移動用戶在哪一個城市,東西南北各個地方的調度沒有充分調用。目前有一部分全國範圍的DNS承載了超過40%的全網用戶
- 不少山寨機的終端local dns設置是錯誤的
- 另外還有一些有線網絡也同樣會遇到的問題,如終端DNS解析濫用、域名劫持、DNS污染、老化、脆弱等。不過對於這些問題,桌面的自愈性會比較好,而在手機上則比較難以解決。
對於DNS的問題,有兩條主要的解決思路:
- 減小DNS的請求、查詢、更新,也就是作DNS緩存
- 在終端配置server list,直接訪問IP,不用DNS
但僅僅這麼作還不夠,由於用戶可能來自國內外不一樣的運營商,還須要進一步優化調度策略:
- DNS緩存須要多創建接入點,用不一樣域名區分
- IP列表須要更新以適應不一樣網絡狀況,要作到主動調度。比如最先咱們只服務好移動用戶就行,保證移動用戶的接入質量優先,由於絕大多數用戶集中在移動;如今國內有三個運營商,用戶分佈的比例在慢慢接近,要區分清楚;智能手機會用wifi,接入的是電信、聯通仍是哪一個運營商,不知道,因此你不可能預先設置場景再if then,必須經過後臺調度能力來解決。
再進一步優化,就產生一種融合的方式:
- 先作域名解析,客戶端直接鏈接解析的IP,能夠用http協議,也能夠用tcp socket
- 多端口、多協議組合:不一樣協議有不一樣的限制,有些只能http,有些只能tcp socket,各類環境都要適應,客戶端不能只支持一種協議
- 終端測速:接入點愈來愈多,接入哪一個合適,要選擇,能夠經過終端測速來選擇最快的。你固然能夠每一次新建鏈接都作測速,可是這樣創建鏈接時間可能會很長;咱們能夠給用戶先創建鏈接後,在後臺根據長期速度監控、當前測速的結果,來作動態調度。也就是說,第一次鏈接可能不是最優,鏈接創建後動態測速,再轉移到最快接入點。更進一步就是創建網絡profile,終端學習的思路。
關於測速採樣的粒度,移動互聯網取IP段是沒用的,比較好的粒度是到網元級別,好比廣東有20多個wap網關,每個網關的狀況都不同,這就是一個比較合適的粒度。
最後強調一個全部的接入調度原則:不要把調度邏輯寫死在客戶端,必定要由後臺完成。
4.3 協議優化
協議參數優化這塊就簡單列一下,是長期運營過程當中總結的一些經驗,在啓動移動互聯網服務時做爲運營的規範,能夠少走不少彎路:
- 關閉TCP快速回收
- Init RTO不低於3秒
- 初始擁塞控制窗口不小於10。由於大部分頁面在10kB如下,不少請求在慢啓動階段已經結束,改成10能夠下降小頁面資源傳輸時延。內容越大,這個選項的效果就比較不明顯。
- Socket buffer > 64k
- TCP滑動窗口可變
- 控制發包大小在1400字節如下,避免分片
協議優化的原則總結下來是這麼幾條:
- 鏈接重用
- 併發鏈接控制
- 超時控制
- 包頭精簡
- 內容壓縮
- 選擇更高效率的協議。不管是TCP、HTTP、UDP、長鏈接、GZIP、SPDY、WUP仍是WebP,每一種協議、方案都有其道理,沒有最優,只有是否適合你的產品和服務特色,須要你們在運營過程驗證和取捨。
4.4 WAP接入點優化
關於WAP接入點優化,可能有些人會說,咱們的App是高端大氣上檔次的應用,是否是就不用作WAP優化?實際上咱們的統計顯示,目前有5%-20%的用戶選擇的接入點是*WAP(CMWAP、3GWAP、CTWAP),這甚至包括一些iPhone終端。實際上,WAP網關本質是個代理,不徹底是落後的東西,隨着技術的進步也在演進,之後在組網架構中可能有綜合網關、內容計費網關來取代目前的WAP網關,因此建議也要一併考慮。如下是作WAP優化須要注意的一些問題:
- 資費提醒頁面
- 302跳轉處理
- X-Online-Host使用與處理
- 包大小限制
- 劫持與緩存
- 正確獲取資源包大小
4.5 業務邏輯優化
一、簡化邏輯:交互繁瑣的內容儘可能用標識更新。舉一個例子,咱們在老版的手機QQ上作過一個測試:假如我有100個好友,用手機QQ完成登錄,完成好友列表更新一遍,須要3.5分鐘。這確定是不合理的。建議用信令狀態來通知是否須要更新,同時合理利用緩存。在好比玩遊戲,好友給你送了不少星星,是讓用戶一次一次點仍是批量點?從優化的角度確定是批量點,從用戶體驗的角度這也更加舒服。
另外一方面,延長域名圖標的緩存時間也能夠有效地優化訪問次數。咱們把手機騰訊網圖標的緩存時長從120分鐘延長到2天后,訪問次數優化了差很少35%。
二、柔性可用:這個意思就是在網絡質量好的時候給高清大圖,很差的時候先給用戶看小圖,點一下再拉取原圖。舉一個極端的例子,好比萬一地震了,基站毀掉20%,用戶要給家人報平安,這時候產品上就必須優化,好比只發送文字,合理降3,低網絡消耗。另外在響應很慢的時候,須要給用戶一些合理的頁面提示,好比提示用戶再過5秒會發送,因此你不要一直刷屏,這也能夠減小訪問對後臺服務、對網絡的衝擊。
五 實戰演示
5.1 一個最優調度設計示例
上面說了那麼多,這裏就給出一個實例幫助你們更直觀的理解。
這裏給出一個DNS系統設計來實現最優調度。其拓撲結構以下:
TGCP SDK的職責:
- 用HTTP的Get/Post方法從DNSvr獲服務器和DNSvr自己的最優接入點列表。Get/Post方法的查詢參數包括uin/openid、客戶端版本號、IP列表的MD5(注意IP順序)、域名列表、VIP、ServiceID等。
- 緩存訪問服務器和DNSvr的IP列表,以及其它元數據(好比IP列表等),且以APN爲主鍵。
- 知足必定的條件下,要主動更新緩存的IP列表,例如緩存過時。
Tconnd的職責:
- 路由查詢請求給活動的DNSvr;
DNSvr的職責:
- 根據靜態和動態策略來決定客戶端的「最優接入點」。靜態策略:根據uin/openid、客戶端版本號或者強制規則來決定IP列表;動態策略:燈塔根據測速數據動態決定用戶的服務器接入點。
- 支持以手動或自動的方式拉黑某些IP。自動方式:由服務器的接入tconnd向DNSvr上報其是否存活(須要向多個點上報,包括用公網IP上報),若是在必定時間內沒有接收到上報或者上報消息中明確全部的邏輯服務器已經掛掉,則自動拉黑相應的IP。若是業務恢復,則自動激活相應的IP。若是項目組接入TGW,對於某個IP和端口是否可用,則須要考慮進程與VIP的映射關係。
- 在tcaplus中緩存燈塔的計算結果。此時要求DNSvr可以根據客戶端IP判斷所屬的國家、省份、運營商和網關(能夠經過訪問MIG的IP庫實現)。若是緩存了燈塔的計算結果,當緩存超時後,要從新從燈塔拉取相應數據。
燈塔的職責:
- 根據客戶端IP和服務器接入點IP,返回最優的接入點列表,包括IP的排序,以及客戶端接入的國家、省份、運營商、APN和網關。
Tcaplus的職責:
- 保存接入的IP列表和端口、靜態策略,或緩存燈塔的計算結果;
主要的流程:
客戶端批量解析域名流程
- TGCP以APN和域名列表爲關鍵字查詢緩存,若是存在且沒有過時,則直接把IP返回給用戶。若是指定強制解析域名列表,則跳過此步驟;
- TGCP用預配置或緩存的IP向DNSvr發起查詢請求,若是成功返回結果,則執行步驟3,不然,重試IP列表中的其它IP,若是都失敗,則用域名訪問DNSvr。注意:若是是結果格式不正確,則使用上次的IP重試,不要更換IP重試。
- DNSvr比較客戶端IP列表和當前最新的IP列表的MD5,若是相等,則告訴客戶端不須要更新本地緩存。不然,TGCP把接入服務器和DNSvr的IP列表寫入本地。注意:在訪問服務器時,這些IP的優先級要高於靜態配置在客戶端的IP。
客戶端使用域名訪問服務器流程
- 若是本地存在有效的IP(即存在對應APN的IP列表,且沒有失效),則使用IP訪問服務器。
- 不然,發起「客戶端批量解析域名流程」後,再訪問服務器。
服務器接入tconnd主動上報狀態流程:
- Tconnd週期性向DNSvr上報心跳消息,其中包含本接入點是否可用的信息。
- DNSvr在必定的時間內沒有收到心跳消息或者相應的接入點不可用,則把相應的IP和端口拉黑,黑掉的IP不在下發給客戶端。
注意:實際部署的時候,接入的Tconnd要向多個DNSvr接入tconnd上報。
向客戶端主動push接入點列表的流程
- 當TGCP鏈接到服務器接入的Tconnd時,Tconnd要向DNSvr發起請求,以校驗當前接入IP的質量和時效性。若是IP列表發生變化,Tconnd要把最新的IP列表下發給客戶端緩存起來。
- 當TGCP下次訪問服務器時,則使用最新的IP列表。
客戶端訪問DNSvr失敗的流程
- 若是訪問DNSvr失敗(包括IP+域名),若是配置了本地IP,則直接用IP訪問服務器,不然用域名訪問。
優化傳輸層協議設計
在原有tconnd支持的可靠UDP的基礎之上,添加如下邏輯:
- 數據壓縮;
- 數據加密;
- 合併多個數據包;
- 支持流式數據傳輸,便於控制每一個UDP包的大小,也便於數據加密和壓縮;
- 可選地支持改進的擁塞控制算法;
- 即便沒有接收到ACK包,也須要主動重試以發送的數據包;
5.2 Hybird開發下的一些優化
要處理在弱網絡下的加載速度,那麼咱們要先肯定一下咱們的整個APP在哪一個地方加載的速度如何,最長的加載路徑在哪裏,咱們從而纔有針對性的進行優化與修改。
5.2.1 WebView
若是是對是APP中內嵌的webview網頁,針對網頁體驗優化已經由來已久了。咱們可使用Chrome的開發者模式,調整到Network模式下,將網絡條件設置爲3G去請求網頁,那麼咱們就可以看出來一個網頁加載的速度主要都耗費在哪一個地方,以下圖所示:
固然,html的加速方式有不少種
- 使用gulpgrunt進行打包壓縮:jscss資源壓縮,CSS Sprites合併等。
- 使用font-awesome替換圖片:字體能夠很好的兼容,無限放大,經常使用的圖片都有
做者:cosWriter 連接:https://www.jianshu.com/p/f7600907d355 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。