無限網絡性能 -- 移動網絡優化

高速瀏覽器網絡性能 -- 第二部分 無線網絡性能 -- 第8章 移動網絡優化



首先,通過長連接把延遲減到最小,把你的服務器和數據放在地理上離用戶近的地方,優化你的TLS部署,還有我們曾經談到的所有其它協議優化,這些對移動應用來說尤爲重要,延遲和吞吐量總是很珍貴。類似的,所有Web應用性能的最佳實踐也同樣適用,第10章會談到。

然而,移動網絡對我們的性能策略有一些新的、特定的要求。由於設備環境限制(the form factor of the device)、無線接口獨特的性能特徵、電池壽命的影響,設計移動網絡應用需要仔細規劃並思考內容的呈現。
可能是因爲展示層最容易控制,所以諸如響應式設計這樣的主題,往往受到最多的關注。然而,大多數應用曇花一現,常常是由於對網絡性能不正確的設計假設導致的:相同的應用協議,但不同的物理髮送層有不同的限制因素,如果未加以考慮,將導致響應慢、高延遲變化,最終給用戶帶來糟糕的體驗。糟糕的網絡決策也會嚴重影響設備的電池壽命,這無疑於雪上加霜。
這三個限制條件沒有通用的解決方案。我們有展示層的最佳實踐,也有針對網絡和電池壽命性能的最佳實踐,但它們常常是有矛盾的。要靠你和你的應用找到你需求的均衡。有一點是確定的,無視這些限制因素,你肯定走不了多遠。
有鑑於此,我們將不會過多討論展示層,因爲不同的平臺,不同類型的應用差別很大 -- 而且,有很多書籍專注於這一主題。無論用的是移動還是聯通,Android還是iOS,都會受到同樣的限制,the radio和電池,這是我們本章重點討論的問題。

在這一章中,術語“移動應用”採用它最寬泛的定義:所有我們關於移動網絡的性能的討論同樣適用於native applications,與瀏覽器運行的平臺、應用,瀏覽器廠商無關。

節省電池電量


一談到移動,省電對各方都是一個很關鍵的問題:設備製造商,運營商,應用開發者,還有我們的應用程序用戶。如果有疑問,或者想知道爲什麼或某個移動行爲怎麼樣表現合適,就問一個簡單的問題:它對電池壽命有什麼影響和改進?事實上,這是你在設計應用程序的每一個功能時應該要問問的好問題。
移動網絡的網絡性能天生與電池性能有關。事實上,無線電接口的物理層特別針對電池壽命做了優化,以應對如下限制:
  • 全功率使用廣播會在幾小時耗幹一個充滿的電池
  • 無線網絡一代比一代要求更高的發送功率
  • 無線電是僅此於屏幕的耗電大戶
  • 無線電耗電量是非線性的,這與數據傳輸模式有關
牢記這一點,移動應用應該以最大限度降低對無線接口的使用爲目標。這不是說,你應該完全避免使用網絡(the radio);畢竟我們正在創建依賴於網絡訪問的聯網應用!然而,因爲保持網絡(the radio)激活是如此耗電,所以我們的應用程序應該在網絡激活時儘可能多的傳輸數據,之後儘量不做額外的數據傳輸。總之,應該避免斷斷續續傳輸數據。


儘管WiFi也使用無線電接口來傳輸數據,但我們應該認識到WiFi的運行機制與2G, 3G, 4G移動網絡有根本的不同,認識到這一點是很重要的。相應WiFi的延遲、吞吐量、電量配置也與它們不同。結果是,WiFi和移動網絡的網絡行爲通常是不同的。

使用AT&T Application Resource Optimizer測量電量消耗
儘管都很重視優化電量使用,當目前大多數平臺仍然缺乏幫助開發者測量和優化他們的應用的必要工具。謝天謝地,有第三方工具可用,比如由AT&T開發的免費的Application Resource Optimizer(ARO)工具包。
ARO由兩部分組成:收集程序和分析程序。收集程序是一個運行在後臺的Android應用,它截獲發送的數據包,無線電活動,以及與手機的其它交互。爲了獲得一個使用軌跡,首先加載收集程序,點擊記錄,然後同你的應用程序進行交互,最後把跟蹤記錄複製到你的系統中進行分析。
有了跟蹤記錄之後,你可以使用分析程序打開它,然後就可以一窺你的應用相關的無線電狀態、電量消耗、還有流量模式。
分析器的一個偉大功能之一是它爲通常的性能陷阱提供建議,比如沒有壓縮、冗餘數據傳輸等等。
值得注意的兩件事情:電池消耗與無線電狀態與指定的設備模型和無線網絡類型相關。換句話說,數據是基於所用模型中指定的參數進行估計的,而不是對當前所用設備的確切測量。
最後,收集程序只有Android版的,但ARO分析程序能夠接受有tcpdump或則其它兼容工具生成的any regular packet trace(pcap)文件

消除週期性和低效率的數據傳輸


事實上,無論傳輸的數據量多少,移動無線電都會在一個固定的電量消耗狀態與全功率狀態之間循環轉換,這告訴我們,當談到電池時,沒有所謂的“小請求(small request)”。間隙性的網絡訪問是反移動網絡性能的模式。看 “Inefficiency of Periodic Transfers”。事實上,對該邏輯進行擴展就產生了下面的規則:
  • 移動網絡上做輪詢是相當昂貴的;儘量不要使用。
  • 儘可能使用推送(push delivery)和通知
  • Outbound和inbound請求應該被合併和聚合
  • 非關鍵請求應該被推遲到無線電激活時才發送
通常,推送要比輪詢更有效率。然而,非常頻繁的推送流也會很耗電的。當你需要一個實時更新時,你應該考慮如下問題:
  • 最好的更新間隔是多久,它符合用戶的預期嗎?
  • 可以使用自適應策略而不是固定更新間隔嗎?
  • inbound和outbound請求可以被合併爲幾個少一些的網絡調用嗎?
  • inbound和outbound請求可以被推後一點嗎?
對於推送(push delivery),能夠系統提供的推送服務的本地應用程序(native applications)應該儘量使用。web applications,可以使用server-sent events(SSES)和WebSocket推送來最小化延遲和協議開銷。儘可能避免使用輪詢和昂貴的XHR技術。

基於自適應間隔,用戶偏好,甚至設備的電池電量,一個把多個通知合併爲一個推送事件(a single push event)的簡單聚合策略,就能夠大大改善任何應用程序的電量曲線,特別是常常依賴於這種類型網絡訪問模式的後臺應用。

Nagle算法和高效的服務器推送(Efficient Server Push)
TCP愛好者肯定能認出請求聚合與捆綁建議就是Nagle's算法,不過要把它在應用層重新實現!Nagle算法試圖把多個小的TCP消息合併爲一個packet以減少協議開銷和發送到線上的包的數量。毫不奇怪,我們的移動應用可以從該技術的利用中獲益頗多。
該策略的一個簡單實現是,在服務端根據時間、數量、大小來聚合消息,而不是有一個消息就觸發一次推送。更先進的,顯然更具效率的策略是只有在客戶端的無線電處於激活狀態時才推送更新 -- 例如:推遲消息直到客戶端發起一個請求或者利用能夠感知客戶端無線電狀態的第三方服務。
例如,爲Android和Chrome提供消息推送APIs的Google Cloud Messaging(GCM),它能夠聚合消息,當而且僅當設備激活時推送更新:服務器推送它的消息到GCM,GCM確定最佳的推送時間。
不幸的是,至今沒有跨瀏覽器的API爲所有客戶端提供像GCM這樣的體驗。然而,W3C Push API,將來可能會解決這個問題。

間隙性的beacon request,比如audience measurement pings和實時分析(real-time analytic)能夠輕易否定所有你細心完成的電池電量優化。這些pings在有線網絡中甚至WiFi網絡中基本是無害的,但在移動網絡上成本巨大。這些beacons(信標?)需要立即發送嗎?很可能你可以簡單的記錄並推遲這些請求直到下一次無線電激活。捎帶你的後臺pings(Piggyback your background pings),密切關注你代碼中第三方庫的網絡訪問模式。
最後,到目前爲止我們集中關注電池,由於RRC狀態轉換,某些技術,比如progressive enhancement和incremental loading,所需的間隙性網絡訪問還會導致大的延遲。回想一下,在移動網絡中,每一個狀態轉換,都會引起一個高控制面板延遲,這可能帶來幾百至上千毫秒的額外延遲 。

計算後臺更新的能量成本
爲了說明輪詢對電池壽命的影響,讓我們來做一些簡單的數學。這些數字不準確,不過一個典型的3G/4G手機大概就在這一範圍:
  • 電池容量爲5watt-hours,或者18,000焦(5Wh x 3600 J/Wh)
  • 從Idle狀態轉換爲連接狀態再回來消耗10焦耳的能量
  • 1分鐘間隔輪詢每小時消耗600焦耳能量
  • 600焦耳是電池容量的3%
單個應用程序每小時就消耗了可用電池電量的3%!只需要一對非重疊輪詢的應用程序就能夠在一早上耗幹你的電池。公平的講,一個頻繁的、未緩衝更新推送應用程序會有更高的電量消耗。
電池壽命優化和頻繁更新是天生的冤家。根據你的應用的需求確定優化策略:bunding of updates,自適應更新間隔,pull vs push,等等。再使用ARO或者類似工具測量影響並做相應調整。

Eliminate Unnecessary Application Keepalives


任何TCP或UDP連接的連接狀態和生命週期與設備上的the radio狀態都是相互獨立的:the radio處於低耗電量狀態,同時連接由運營商網絡維護。當一個新的來自外部網絡的包到達時,運營商無線網絡將通知設備,促使它的radio進入連接狀態,恢復數據傳輸。
應用程序不必爲了保證連接不被丟棄而始終保持the radio處於"active"狀態。不必要的應用保活(keepalives)會對電池壽命性能有巨大的負面影響,而且常常是因爲對移動無線網絡的工作原理有誤解而使用的。Refer to “Physical Layer vs. Application Layer Connectivity” and “Packet Flow in a Mobile Network”

大多數運營商設置了5-30分鐘的NAT連接超時。因此,你可能需要一個定期的(5分鐘)保活以維持一個連接不被丟棄。如果你發現自己需要更頻繁的保活,那就檢查你自己的服務器,代理,負載平衡配置。

預期網絡延遲開銷(Anticipate Network Latency Overhead)


在一個移動網絡中,單個HTTP請求,總是會帶來幾百到幾千毫秒的網絡延遲開銷。部分是由於高往返延遲導致的,但我們要記住還有DNS、TCP、TLS開銷(圖8-2),以及控制面板成本!

       

最好的情況是,the radio已經處於激活狀態(in a high-power state),DNS已經預解析好,也有一個可用的TCP連接:客戶端可能能夠利用一個現有連接,從而避免創建一個新的連接的開銷。然而,如果連接處於忙碌狀態,或者根本不存在,那我們就不得不引入一系列的額外往返延遲,之後才能發送應用數據。
爲了說明這些額外網絡延遲的影響,讓我們做一個樂觀的假設,4G網絡RTT爲100ms,3.5G網絡RTT爲200ms:


在一個3G網絡中,爲重新創建一個radio上下文,RRC控制面板(control-plane)延遲單獨添加了幾百到幾千毫秒的開銷!一旦radio激活,我們可能需要解析主機名爲IP地址,然後執行TCP握手 -- 兩次網絡往返。如果需要一個安全通道,我們可能還需要另外兩次網絡往返(see “TLS Session Resumption”)。最後,可以發送HTTP請求了,這增加至少另外一個往返。
我們還沒有考慮服務器響應時間或響應大小,這可能需要多次往返,而我們已經引入了半打往返延遲了。往返次數乘以往返時間,我們看到3G網絡的延遲開銷超過了1秒,4G網絡有大約半秒。

考慮RRC狀態轉換 (Account for RRC State Transitions)


如果移動設備已經空閒了幾秒鐘,你應該假定和預期第一個數據包將招致幾百,甚至上千毫秒的額外RRC延遲。一般說來,4G網絡增加100ms,3.5G增加150 - 500ms,3G網絡增加500 - 2500ms,這是一次性的控制面板成本。
RRC是專門設計來幫助減少操作耗電的radio的成本的。然而,由於各種各樣的計時器(the various timers),計數器(counter),必需的網絡協商以及不同的radio狀態轉換產生的開銷的存在,我們節約的電池電量很容易被延遲的增加和低吞吐量抵消掉。雖然如此,RRC在移動網絡中也是一個不爭的事實 -- 沒有其它的辦法 -- 如果你想爲mobile web創建優化的應用,你在設計時必須把RRC牢記於心。
快速總結下我們已經瞭解的RRC:
  • 不同的無線標準的RRC狀態機是不一樣的
  • RRC狀態機由設備的the radio網絡管理
  • 當有數據必須發送時,RRC狀態提升至大功率狀態
  • 超過了網絡配置的超時時間後,RRC狀態降至低功耗狀態
  • (4G)LTE狀態轉換花費10 - 100ms
  • (4G)HSPA+狀態轉換花費與LTE相當
  • (3G)HSPA和CDMA狀態轉換可能花費幾秒
  • 每次網絡傳輸,無論大小是多少,耗費的能量都是一樣的(incurs an energy tail)
我們已經討論了爲什麼省電對移動應用程序是一個多麼重要的目標,我們還重點討論了低效率和間歇性傳輸的壞處,那是超時驅動的RRC狀態轉換的直接結果。然而,還有一件事情你需要記住:如果設備radio已經空閒了(Idle),那在移動網絡中初始化一次新的數據傳輸將會導致一個額外的延遲,如前所述,這個花費從最新一代網絡的100ms到3G和2G網絡的幾秒。
在應用程序看來,網絡總是在線,不過那是一個幻覺,由RRC控制的物理層或者radio層持續不斷的連接、斷開連接。表面看來,這不是一個問題,但許多不知道其中緣由的用戶,其實很容易注意到這種由RRC附帶的延遲。

從網絡通信中解耦用戶交互(Decouple User Interactions from Network Communication)


一個設計良好的應用感覺會很快,這是通過提供即時反饋,即便在當前連接很慢或者請求需要花很久才能完成的情況下,來達到的。不要把用戶交互、用戶反饋和網絡通信耦合在一起。爲了提供最好的用戶體驗,應用程序應該在幾百毫秒內確認用戶輸入。see “Speed, Performance, and Human Perception”.
如果需要一個網絡請求,那就在後臺初始化它,並提供即時UI反饋確認用戶輸入。單獨的控制面板時延往往會推動你的應用程序爲提供即時用戶反饋分配預算。要考慮高延遲的情況 -- 你不能消除由核心網絡和RRC附帶的延遲 -- 確保你的設計團隊在設計應用時意識到這些限制的存在。

可變網絡接口可用性設計(Design for Variable Network Interface Availability)


用戶不喜歡遲鈍的應用,但因爲“暫態網絡錯誤”而奔潰的應用程序,纔是最糟糕的體驗。你的移動應用在面對通常的網絡失敗時應該足夠健壯:主機不可達,突然下降的吞吐量或延遲增加,抑或連接的直接損失。不像有線網絡世界,你不能簡單的假定連接一旦創建,它就一直在那。用戶可能在移動,可能進入一個干擾嚴重,或有很多激活用戶,或者覆蓋不佳(plain poor coverage)的區域。
此外,就像你設計網頁時不能只考慮最新的瀏覽器一樣,你設計應用時也不能只考慮最新一代的網絡。如我們之前所述(“Building for the Multigeneration Future”),即便手握最新的手機,你也得不斷的在4G, 3G, 設置2G網絡間轉換,因爲無線網絡環境變化多端。你的應用程序應該訂閱(subscribe)這些接口轉換,並做相應調整。

在移動網絡唯一不變的就是變換。廣播通道的質量基於與信號塔之間的距離,與附近用戶的衝突,周圍環境的干擾,還有其它很多因素,它總在不斷的變化。考慮到這一點,對帶寬和延遲做各種形式的估計以優化應用程序可能頗令人心動,不過我們應該,也最好是把估計的結果,看做是瞬時數據。

iPhone 4“天線門”事件是一個說明radio性能的不可預測性的極好的例子:接收質量受你手持姿勢影響,這就是臭名昭著的“你拿錯了。”

移動網絡上的延遲和帶寬估計在幾十毫秒到數百毫秒,至多1秒之內是穩定的,不能再長了。因此,像自適應比特流這樣的優化對於長期實時流是很有用的,比如視頻,採取的做法是,緩衝幾秒鐘的數據塊,這些帶寬估計肯定不能夠緩存起來或用於將來確定可用吞吐量:即使在4G網絡上,可能你剛測得的吞吐量是幾百Kbit/s,然而你移動了幾英寸之後,速度立馬就提升至Mbit/s。

移動網絡上的流媒體應用


移動網絡上的流媒體應用是一個棘手的問題。如果你需要執行大量下載並且確信整個文件都會被用到,那麼你應該一次性把整個文件下載下來,然後讓radio進入Idle狀態,越長越好。
然而,如果因爲文件太大,或用戶限制你不能下載整個文件,那你應該採用自適應比特流,持續調整以適應網絡吞吐量的不斷變化。你將付出高昂的電池成本,不過這樣做至少提供了最好的用戶體驗!另外,你應該要提示用戶打開Wifi。
端到端的帶寬和延遲估計在任何網絡上都是一個困難的問題,在移動網絡上就更甚了。不要去估計,因爲你得到的結果是錯的。相反,你應該使用關於這一代網絡的粗粒度信息,並相應的調整你的代碼。更清楚的講,知道網絡的類型並不能對端到端的性能做任何保證,它只能告訴你關於第一個無線跳的延遲和運營商網絡的端到端性能的重要數據。see“Latency and Jitter in Mobile Networks” and Table 7-6.
最後,除了吞吐量和延遲外,你還應該考慮連接丟失:假定這種情況經常發生,而不是當做例外。當網絡不可用或發生一個暫時性的錯誤時,你的應用程序應該最大限度保持運行,並基於請求的類型和特定的錯誤做出合適的響應:
  • 不要緩存和猜測網絡狀態
  • 分派請求,監聽失敗,診斷髮生了什麼
  • 暫態性錯誤將會發生;做好應對計劃,使用恢復策略
  • 監聽連接狀態,預測最好的請求策略
  • 對請求重試使用退避算法;不要使用永久自旋
  • 如果掉線了,記錄並在之後可能的時候分派請求
  • 利用HTML5 AppCache和localStorage實現離線模式

Burst Your Data and Return to Idle


移動無線接口被優化用於突發性傳輸,你應該儘可能的利用這一性質:把你的請求組合在一起,儘可能多的下載,越快越好,然後讓radio返回到Idle狀態。這一策略將會帶來最好的網絡吞吐量並最大限度延長設備電池壽命。

最精確的估計網絡速度的方式,就是使用它!最新一代的網絡,比如LTE和HSPA+,以一毫秒的時間間隔動態分配資源,並優先考慮突發性數據流。要快,很簡單:批處理或預取儘可能多的數據,然後讓網絡休息。

一個重要的推論是,漸進式的資源加載(progressive loading of resources)對移動網絡可能弊大於利。如果一小塊一小塊的下載內容,我們的應用程序就面臨更高的吞吐量和延遲波動,更別提更高的用於操作radio的能源成本了。解決方法是,預測用戶下一步所需要的,提前下載下來,讓後讓the radio進入Idle狀態。
  • 如果你需要獲取一個大的音樂或視頻文件,考慮提前把整個文件下載下來,而不是一塊一塊慢慢下載。
  • 預期應用內容,創建指標和統計模型,以幫助識別哪些內容適合提前下載。
  • 提前預期第三方內容,比如廣告,並在需要的時候添加應用邏輯展示和更新它們的狀態。
  • 消除不必要的間歇性傳輸,see   “46% of Battery Consumption to Transfer 0.2% of Total Bytes”.

Offload to WiFi Networks


當前的行業估計顯示幾乎90%的全球無線通信源於室內,常常是有Wifi連接的區域(說明大部分手機流量是在有Wifi的情況下產生的)。最近的4G網絡在延遲和吞吐量方面與Wifi相當,不過你知道,營運商仍然很大可能會限制月流量:移動網絡訪問對用戶來講還是很貴。此外,Wifi連接的電池效率更高(see “3G, 4G, and WiFi Power Requirements”),因爲大數據傳輸不需要一個RRC。
任何時候,特別是當你正在創建一個數據密集型應用,你都應該儘可能的利用Wifi連接,如果Wifi是關閉的,你應該考慮提示用戶打開Wifi,這樣可以改善體驗和降低成本。

應用協議或應用最佳實踐


我們的網絡基礎設施的層次架構的一個偉大性質是,它對傳輸層抽象了物理載體,傳輸層爲應用協議抽象了路由和數據傳輸。這種層次分離提供了良好的API抽象,但爲了最好的端到端性能,我們仍然需要考慮整個協議棧。
在本章,我們討論了移動網絡物理層的獨特性質,例如,RRC的存在,設備的電池壽命問題,移動網絡的路由延遲問題。然而,在前面的幾章中,我們已經討論了在物理層之上 傳輸和會話協議,它們優化也是一樣重要的,甚至更加重要。 
重用長連接最小化延遲,地理定位靠近客戶端的服務器和數據,TLS部署優化,以及我們之前強調的所有其它優化,它們在RRT很高,帶寬很珍貴的移動網絡更爲重要。
當然,我們的優化策略不會止步於傳輸和會話協議;它們只是基礎。此外,我們必須同時考慮不同的應用協議(HTTP 1.0, 1.1 和 2.0)對性能的影響,還有web應用最佳實踐 -- 繼續往下讀,我們還沒完呢。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章