有贊移動性能監控平臺(二)
作者:陳明義
一、前言
性能和穩定性一直是 App 質量體系中最基本和最關鍵的一環。 而移動端業務快速迭代的過程中,開發同學對性能的關注不足,量變引起質變,App 的卡頓嚴重影響商家的日常經營,商家對性能的吐槽和抱怨越來越嚴重。而面對商家反饋的性能問題,由於缺乏現場信息,問題的排查既被動又困難。我們急需一個系統化的解決方案,需要有自己的 APM(Application Performance Management),可以通過它來發現問題,並且能依靠它的數據來指導我們進行性能優化。
二、整體設計
系統主要分爲兩個部分:
-
移動端上的「性能檢測」,主要負責數據的採集。
-
後端的「數據處理」,主要包含數據的清洗、解析、存儲、報警等。
2.1 性能檢測
2.1.1 慢方法 & ANR 檢測
有贊零售的業務複雜度非常高,且由於業務場景的特殊性,有大量的複雜業務邏輯處理都是在移動端上做的,本地存在大量的 DB 操作、數據同步、複雜計算......,此外收銀設備的配置和性能相比於手機有很大的差距,這些都對我們提出了很大的挑戰。卡頓問題也是我們面臨的主要難題之一,爲了解決這個問題,我們首先要解決方法運行效率的問題,找出應用中執行效率不滿足要求的方法,通過優化這些處理邏輯,提高方法運行效率,進而提升整體的性能。
總體流程分爲四步:
**Step1:編譯期自動採集需要性能檢測的方法。**過濾不需要進行檢測的方法或類,爲每個方法分配一個獨立 ID(包括二方庫及三方庫的方法),並生成方法 ID 與方法簽名的映射文件。
**Step2:編譯期對方法進行插樁。**通過插樁的方式對所有需要檢測的方法進行插樁,在每個函數的函數體前後會自動插入 i 和 o 方法,入參爲方法 ID,這樣就可以很方便的對執行時間進行檢測。
**Step3:運行期進行性能檢測。**比如慢方法和 ANR 的檢測是通過記錄 i 和 o 方法的時間並進行存儲,會記錄每個方法進入和離開的時間,當執行時間超出我們設定的閾值時,會將方法的信息進行上報,方便後面對數據進行處理。
**Step4:收集卡頓現場信息。**監聽每一幀的變化,卡頓發生時,會有單獨的線程去收集堆棧信息以及現場環境信息(包含:設備信息、CPU 使用情況、內存、磁盤信息等)。
2.1.2 線程池檢測
在 Android 開發中我們通常會將一些耗時任務放到子線程中進行操作,否則可能會阻塞 UI 線程,引起 ANR、卡頓等問題。而我們的 App 中就存在大量的異步任務,包括網絡請求、本地大量的 DB 操作、定時輪詢等任務,而所有的這些異步任務都在同一個線程池中運行 (IO 線程池),這樣就帶來了一個問題:當網絡請求比較慢的時候,線程池會快速堆積任務,再加上不斷輪詢的任務,線程池極易被打滿,本地快速的一些異常任務就容易被阻塞住,造成耗時短的任務等待耗時長的任務。
爲了解決這個問題,我們需要對線程池進行更細粒度的劃分,考慮到我們應用的特性,我們對主線程池的定位改爲:爲大量、快速的本地任務提供支持,這樣我們就需要將一些「耗時長」、「頻率高」的任務進行治理,將這些任務分離出我們的主線程池,我們需要監控線程池中的任務,能通過監控的數據挖掘異步任務的優化點,同時爲線程池的配置調整提供可度量的指標。
-
任務提交到線程池。拉取每個任務的調用棧信息,解析並記錄任務的發起點以及任務的提交時間。同時可以分析此時線程池的負載狀況(結合 activeCount、corePoolSize、queueSize),如果負載達到閾值,則拉取出當前所有的任務,分析是否存在明顯有問題的任務(比如同一任務發起多次等)。
-
任務開始執行。記錄任務開始執行的時間。
-
任務執行完成。與任務開始時間做差值,計算並記錄任務的執行時間,如果任務的執行時間超出閾值,則會進行上報。
總體流程如下:
2.2 數據處理
2.2.1 整體流程
(1)方法映射文件記錄。應用打包時會自動執行上面的編譯期處理流程,生成方法映射文件,並上傳到 APM Server,然後進行方法映射數據的處理。
(2)性能數據同步。卡頓發生時,會上報相關數據。數據會通過 DP(數據平臺) 進行清洗、計算和統計 (比如前一天性能報告統計),然後通過 Hive -> DB 流程同步到後端應用的 DB 中。
(3)數據解析。後端應用會對數據中的卡頓堆棧進行解析 (把 ID 解析成方法名)。
(4)數據聚合。解析完後需要對同一方法的數據進行聚合 (包含跨版本、跨補丁的數據處理,比如 A 方法可能在 1.0 版本 ID 是 11,在 1.0 補丁 1 版本的 ID 是 22,在 1.1 版本的 ID 是 33,需要把他們聚合成一條數據),這樣就能準確的知道每個方法的嚴重程度,每條聚合數據也會記錄對應的解決狀態。
(5)數據分析 & 報警。會結合數據平臺上計算和統計的結果以及數據聚合後產生的數據,產出日報、週報、告警等信息,爲性能變化趨勢提供數據化支撐。
通過上面的方式將同一個方法的問題進行聚合,可以跟蹤所有問題的解決狀態,並能通過數據分析進行性能變化趨勢的監控以及問題的報警。
2.2.2 關鍵節點
(1)數據解析 & 聚合
由於上傳的卡頓信息中只會包含方法的 ID,我們需要在後端對這些數據進行解析,將它解析成具體的方法名,然而由於不同版本、不同補丁生成的方法映射文件是不一樣的,同一個方法在不同的版本對應的方法 ID 是不一樣的,而我們需要將同一個方法引發的問題進行聚合,這樣纔能有效的跟蹤每個問題的解決狀態。而是否是同一個方法的認定標準爲:完整類名 + 方法名,這樣就能幫助方法的唯一性。
整體解析 & 聚合流程如下:
整個監控平臺數據雖然經過重重過濾,但是本身的數據量還是非常大的,任由數據無節制的增長會很容易到達我們處理的瓶頸,且這龐大數據中大部分是無需長時間存儲的,我們需要有數據的清理機制,通過清理機制來保證我們數據不至於增長過快:
-
未分配的問題且最近一個月問題不再出現,則這個問題大概率以後不會再發生了,針對這種問題我們會直接清除問題的所有信息,不會再跟蹤這個問題。
-
已分配但未標記解決的問題且最近一個月問題不再出現,這種問題一般是問題已經修復但是沒有及時修改狀態,我們會把問題的狀態修改爲自動失效。
-
狀態流轉已結束的問題(包括已處理、已忽略、自動失效的問題),我們會保留最新的一條明細數據進行存檔,剩餘的明細數據會全部清除。
-
方法映射表中會存儲過往所有版本的所有方法信息,然而其中絕大多數方法其實是沒問題的(比如簡單的 a+b),所以這裏我們會對最近一個月解析時沒有訪問的方法進行清除(解析時沒訪問的方法意味着這個方法沒發生卡頓問題)。
-
同一個版本可能會上傳多次方法映射表信息,而真正發佈的只會有一個,因此我們會去發版平臺獲取某個版本正在發佈的信息,然後把沒有正常發佈的方法映射表數據刪除。
整體清理流程如下:
三、功能介紹
3.1 問題數據
3.1.1 TOP 問題列表
3.1.2 問題詳情
3.2 問題報警
3.3 性能報表
3.3.1 ANR 變化趨勢
3.3.4 線程池卡頓次數
四、未來規劃
-
完善性能監控體系,補足網絡、I/O、線程池、磁盤等方面的監控,通過性能監控的數據指導性能優化。
-
更多維度的數據篩選和過濾能力,能夠更好的對指定設備或門店進行問題跟蹤。
-
更強的數據處理能力,能夠更快速地處理更龐大的數據量。
-
完善系統使用體驗,如:報表呈現、問題分配機制、問題報警等。
-
推廣到公司其它的業務線,幫助解決端上性能監控問題。
五、結語
通過性能監控的實踐以及後續的性能優化,幫助我們更好的解決了性能問題,總結下來它的核心價值在於:
-
對 App 線上真實的性能情況有了數據化的指標,讓我們對性能問題有了更清晰的感受。
-
通過監控的數據指導我們進行性能優化,優化效果也能有數據化的支撐。
-
通過監控的數據能讓我們更快速的發現新引入的性能問題,防止性能不斷劣化,爲 App 的穩定運行提供保障。
-
推動各業務團隊進行性能優化,讓大家能更加重視自己產品的性能問題。
性能監控與性能優化道阻且長,我們也會不斷地在這方面進行更多的嘗試和努力,爲 App 的穩定運行提供更好的保障,做好性能和穩定性的守門員。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/8PwGV9yrclaxiUA-0j65aA