百年前,人們獲取信息的方式是經過書籍、報紙;十年前,人們獲取信息的方式是經過PC、互聯網;現在,在移動互聯網高速發展的環境下,人們獲取信息的方式已經全面轉向了小小的手機。短短几年裏,移動互聯網已經與咱們的生活如影隨行,一部手機走天下再也不是夢想。
移動應用的商業價值在互聯網時代發生了變化,愈來愈多企業經過移動應用爲用戶提供服務,應用改變了商業世界。2016年Q1,用戶從iOS和Android應用市場下載的應用數量高達172億個,94%的應用以火箭般的速度進行更新。更新迭代越快,應用存在的性能問題就越突出,性能問題形成業務降低影響已經佔到25%甚至更多,應用自己的變革迫在眉睫。前端
透視寶mobile APM 從五個維度解析移動應用性能react
移動應用發佈上線以後,因爲缺乏有效的性能監控手段,對於開發和運維來講其架構、應用、程序代碼的執行狀況都是一個黑盒,沒法感知到用戶使用APP的真實感覺,沒法預知應用發生了什麼樣的問題,看不到業務具體數據究竟是怎麼執行,更沒辦法準肯定位到問題,而APM經過如下五個重要維度可以幫你把黑盒子打開。linux
一、用戶從哪來,網絡接入性能怎麼樣?
web
地域分析能夠了解咱們的用戶都是從哪些地域使用APP,各地的響應時間是否存在很大差別,耗時較高的地區根據網絡節點調整CDN,優化網站層面的性能問題。
二、用戶使用的什麼設備,不一樣運營商對網絡響應是否達標?
設備、運營商、APP版本分析能夠幫忙瞭解用戶使用什麼品牌的手機訪問APP應用,不一樣的終端存在不一樣的差別,據統計iPhone6 使用較爲穩定,而華爲設備發生崩潰概率最低,經過這些設備、運營商、APP版本的分析結果能夠在新版本迭代中安排重點測試和適配。
三、用戶作了什麼操做,在APP中的用戶體驗如何?
用戶行爲監控可以將全部用戶在APP中的點擊操做與性能數據關聯,經過HTTP請求響應耗時,請求錯誤,崩潰等維度分析APP中最影響用戶體驗的用戶行爲。而且可分析受到影響的每一位用戶的在APP中行爲操做路徑及流程,協助研發人員還原用戶使用場景從而精準定位問題發生的緣由。
四、APP中是否發生了崩潰、ANR等問題?
崩潰是APP應用中最影響用戶體驗的問題之一,並且是移動開發者最大的痛點,因此收集崩潰日誌、快速定位問題根源是最好的解決辦法。崩潰分析可按APP版本,崩潰趨勢,設備型號,運營商,接入方式,地域崩潰等多個維度分析和統計。
崩潰分析能夠解析崩潰堆棧定位發生崩潰的代碼片斷和行數,而且經過收集分析用戶發生崩潰的設備,接入方式,內存,CPU使用率以及用戶操做的行爲軌跡助研發人員能快速定位問題,還原案發現場。
五、APP前端頁面交互性能和Service端代碼執行效率
APP中的性能問題大致能夠分爲兩部分:一、前端頁面交互性能 二、後端Service端代碼效率。
前端頁面交互性能主要體如今頁面加載緩慢,請求錯誤異常,卡頓等方面,而目前webview在APP開發中已經很是廣泛,對性能的監控需求也愈來愈強烈。咱們提出白屏時間、頁面請求耗時分解、頁面加載資源耗時分解等性能指標,能夠對頁面請求耗時診斷慢在哪一個環節。
頁面響應時間分解,將整個H5頁面加載的耗時分解到網絡請求的每個細節上去。如上圖主要包括:重定向起止時間、緩存起止時間、域名解析起止時間、TCP傳輸起止時間、請求起止時間、響應起止時間、Dom加載起止時間、頁面渲染起止時間等。
圖:H5頁面加載的資源時序圖,明確告知每個資源類型的加載時間。
APP端除了前端的性能問題須要關注,Service端的性能問題一樣不容忽視,因爲篇幅問題本文不作重點介紹,可是須要介紹mobile端與service的端到端的特性。後端
端到端事務分析
針對移動端的事務咱們能夠診判定位到耗時狀況,除了前端頁面的資源加載佔用大量資源外,Service代碼形成緩慢的因素一樣須要準肯定位,因此透視寶提供了端到端事務分析。
移動端嵌入SDK,Service端部署Smart Agent,經過UUID關聯了APP中全部的請求事務,定位後端的代碼執行最慢的方法,SQL語言,參數等指標。
針對HTTP的網絡數據收集主要分爲如下指標:請求時間、網絡吞吐量和網絡錯誤,劫持分析等。
請求時間是指一個http請求從發起請求到接收到服務端的響應,這期間所經歷的時間。這個指標能夠跟蹤後臺接口的響應是否正常,網絡環境是否正常。
網絡錯誤主要是跟蹤url請求過程當中的錯誤,分爲http自己的錯誤和因網絡情況出現的錯誤。
某個客戶的一個杭州用戶在6分鐘內發起了5800屢次請求,請求錯誤率高達98%以上。當時他們不相信那是真實的,後來與客戶交流發現該網絡請求接口存在循環調用,請求接口在請求成功以前會一直循環調用,直到請求成功或是斷網,而這正是形成致使循環請求的真正緣由。
仍是這個客戶,咱們經過Smart SDK發現他的不少API報錯是找不到主機,經確認APP開發在版本迭代過程當中把不少接口廢棄了,但客戶端還在調用,經過HTTP錯誤和網絡錯誤請求分析就能夠幫助客戶清理廢棄的API,保證咱們的業務正常服務。
而作到這一切,只須要嵌入透視寶Smart SDK的兩行代碼, 5分鐘輕鬆實現對APP應用的性能監控,業務運營監控的需求。以往經過用戶投訴和反饋,開發老是最後一個發現問題,而被動的解決問題更是費時費力。使用透視寶後能夠提早發現應用性能問題,快速迭代修復問題,避免用戶流失提高用戶體驗。緩存
移動端性能管理技術實現安全
透視寶Smart SDK自動收集性能數據是不須要埋點的。iOS和Android因爲平臺的差別性實現方式是不一樣的。Objective-C語言具備動態運行時的特性,所以iOS平臺使用Hook機制來攔截方法的執行,從而收集性能數據;而Java語言不具有這樣的特性,但可以對字節碼進行改寫,所以Android平臺使用ASM框架動態注入代碼到相關的方法中收集性能數據。
iOS Smart SDK技術原理網絡
iOS的Hook技術使用Objective-C提供的Method Swizzling機制。Method Swizzling是Objective-C的運行時技術,指的是改變一個已存在的選擇器對應的實現的過程,它依賴於Objectvie-C中方法的調用可以在運行時進行改變——經過改變類的調度表(dispatch table)中選擇器到最終函數間的映射關係。
原理圖以下:
每個Selector(選擇器)對應一個IMP(實現體),經過Method Swizzling能夠動態改變這種對應關係。Swizzling一般被程序開發認爲是一種巫術,容易致使不可預料的行爲和結果。可是若是採起下面這些措施,Method Swizzling仍是很安全的:多線程
一、Swizzling應該在+load方法中實現。
Objective-C中每一個類都有+load和+initialize兩個方法。這兩個方法會被Objective-C運行時系統自動調用,+load是在一個類最開始加載時調用,+initialize是在應用中第一次調用該類或它的實例的方式以前調用。這兩個方法都是可選的,都是隻有實現了纔會被執行。
由於method swizzling會影響全局,因此減小冒險狀況就很重要。+load可以保證在類初始化的時候就會被加載,這爲改變系統行爲提供了一些統一性。但+initialize並不能保證在何時被調用——事實上也有可能永遠也不會被調用,例如應用程序從未直接的給該類發送消息。
二、Swizzling應該在dispatch_once中實現。仍是由於swizzling會改變全局,咱們須要在運行時採起全部可用的防範措施。保障原子性就是一個措施,它確保代碼即便在多線程環境下也只會被執行一次。GCD中的diapatch_once就能夠提供這些保障。
三、始終調用方法的原始實現。系統提供的 API爲輸入和輸出提供規約,但它裏面具體的實現實際上是個黑匣子,在Method Swizzling過程當中不調用它原始的實現可能會破壞一些私有狀態,致使程序運行不穩定。架構
Android Smart SDK技術原理
首先來看看Android app的打包流程
該圖翻譯成技術語言,以下圖
圖中標明瞭sdk中代碼的工做位置:
就是在 .class文件轉化成.dex文件的過程當中,經過ASM框架改寫代碼的。經過對字節碼的讀寫,找到感興趣的方法,加入收集信息的代碼。原生的網絡請求、用戶行爲、頁面加載等方面的性能數據,就是以這樣的方式收集到的。
透視寶端到端技術方案重點不在移動端,而在於後端。移動端只是針對從APP中發出的每一條網絡請求打上標記,後端節點上的Agent接收到該條請求,解析標記,記錄下來,而且打上該節點的標記。最終經過這些標記畫出該條請求所通過的全部節點的拓撲圖,將節點上的應用的性能指標關聯起來。
崩潰信息收集和分析
iOS的崩潰信息收集和分析原理
崩潰信息收集,經過系統提供的異常信息捕獲接口,設置回調函數,捕獲異常信息。經過解析解碼文件,將解碼文件與崩潰信息裏的內存地址結合起來,分析出發生崩潰的位置和代碼段
經過設置系統異常信息收集的回調函數到系統相應的接口上,捕獲系統的異常信息。
崩潰信息解析過程:
一、 從崩潰日誌中獲取代碼行的地址偏移量。(已從前面的崩潰信息中獲取到)
一、 解析符號表文件dSYM, 使用dwarfdump命令從dSYM文件中抽取相關信息。比較經常使用的兩個命令:
dwarfdump -e --debug-info YourPath/YourApp.dSYM/Contents/Resources/DWARF > info.txt
dwarfdump -e --debug-line YourPath/YourApp.dSYM/Contents/Resources/DWARF > line.txt
其中,info.txt文件中包含類文件的具體信息,好比類名,方法名,方法的內存起止地址等。
以下圖所示:
由圖中可知,只要偏移量在0x000681c0和0x00068454之間的代碼,就對應JKBOverviewVC.m文件的 -[JKBOverviewVC tableView:cellForRowAtIndexPath:]函數。
具體崩潰在該函數的哪一行,經過line.txt文件中的內容得出
line.txt文件中,包含函數中每一行代碼的內存地址對應的相關信息,以下圖所示
崩潰日誌中,偏移量在0x000681c0和0x00068454之間的代碼,在這個line.txt文件中就能找到具體的代碼行。至此,iOS的崩潰日誌就分析完成了。
Android的崩潰收集原理
1. Java層的崩潰信息收集原理,以下圖所示:
Java 層的堆棧信息收集是經過定義一個Handler類去實現Thread.UncaughtExceptionHandler接口的void uncaughtException(Thread t, Throwable e)方法,而後,經過在Thread.setDefaultUncaughtExceptionHandler方法將咱們定義的Handler和APP的線程關聯起來。在uncaughtException方法中去收集APP 沒有捕獲的異常,而後將其堆棧信息收集起來。
2. Native層的崩潰信息收集原理,以下圖所示:
因爲Android 底層使用的是linux內核,因此Native層先經過sigaction()函數去註冊咱們須要監視的Crash相關的信號量,同時,修改相關信號量發生的回調函數,在回調函數中咱們經過Android的libcorkscrew.so(5.0版本如下) 和 libunwind.so(5.0及以上版本)提供的打印堆棧函數去收集Native層的堆棧信息,而後經過JNI層回調到Java層,從而收集到native的信息和Java層當前的全部線程信息。
H5頁面的性能數據收集方案
H5頁面的性能數據採集經過注入js代碼來實現的。移動端的H5頁面展現過程,主要分爲數據請求、數據加載、頁面渲染等。而其中數據加載是將H5頁面的數據從服務端一段一段的load到移動端,JS代碼的注入就是在這個階段完成的。
在數據load階段注入js代碼,待數據load完成以後渲染,這樣作既不會影響客戶代碼的執行,也能保證JS代碼可以監控H5頁面的整個生命週期中的用戶操做和頁面加載狀況。
因爲移動端操做系統對webkit進行了高度封裝,開放出來的API還少,以至不能獲取H5頁面的詳細加載狀況,只能藉助於JS代碼,獲取頁面的performance參數,從而獲取到頁面加載的各個性能指標。
Q1:對於react native 是否也能支持?對於原生應用和這種類型的應用支持的程度是否一致?A:咱們目前沒有對React Native的應用作過測試。網絡請求的支持應該是與原生應用的支持一致的;系統級別的崩潰,支持程度也是一致的;加載H5和用戶行爲事件的追蹤,支持程度應該有限。以上結論,須要測試肯定。假如不支持,咱們也將通過迭代,解決該兼容問題。Q二、H5中注入腳本會影響性能麼?A:JS代碼是存在SDK本地的,沒有新的網絡請求產生,JS代碼在H5頁面上工做的時候,並非現場計算,而是直接取得performance的接口;同時修改系統的click事件冒泡取得標籤值和url,而不是進行click方法的動態bound,因此工做過程當中的性能損耗微乎其微。Q 三、除了UI上帶來的用戶體檢,耗電、網絡流量也是用戶所關注的。不是埋點式的行爲數據收集,產生的數據量是怎麼控的?A:一、耗電量能夠經過系統接口獲取到 二、網絡流量目前有統計,咱們的每一條請求都會統計發送字節和接收字節。三、目前行爲數據不支持可配置,只要是有事件發生的行爲,都會記錄。下一步會支持用戶行爲可配置。接下來咱們會支持APP中用戶重點關心的用戶行爲配置,並且這個建模過程會更加清晰簡單,只須要操做APP就能夠完成這個過程了。