有贊移動性能監控平臺(二)

作者:陳明義

一、前言

性能和穩定性一直是 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 線程池),這樣就帶來了一個問題:當網絡請求比較慢的時候,線程池會快速堆積任務,再加上不斷輪詢的任務,線程池極易被打滿,本地快速的一些異常任務就容易被阻塞住,造成耗時短的任務等待耗時長的任務。

爲了解決這個問題,我們需要對線程池進行更細粒度的劃分,考慮到我們應用的特性,我們對主線程池的定位改爲:爲大量、快速的本地任務提供支持,這樣我們就需要將一些「耗時長」、「頻率高」的任務進行治理,將這些任務分離出我們的主線程池,我們需要監控線程池中的任務,能通過監控的數據挖掘異步任務的優化點,同時爲線程池的配置調整提供可度量的指標。

檢測的核心在於監聽線程池的三個節點:

總體流程如下:

通過上面的方式能逐步分離出「耗時長」、「頻率高」的任務,通過對這些任務的優化,最終達到線程池優化的目標。另外由於有了完整的線程池負載情況跟蹤以及任務執行時間數據,我們對線程池的健康度也有了可度量的指標,這也爲我們做線程池的自動化配置提供了參考依據。

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 是不一樣的,而我們需要將同一個方法引發的問題進行聚合,這樣纔能有效的跟蹤每個問題的解決狀態。而是否是同一個方法的認定標準爲:完整類名 + 方法名,這樣就能幫助方法的唯一性。

整體解析 & 聚合流程如下:

(2)數據清理流程

整個監控平臺數據雖然經過重重過濾,但是本身的數據量還是非常大的,任由數據無節制的增長會很容易到達我們處理的瓶頸,且這龐大數據中大部分是無需長時間存儲的,我們需要有數據的清理機制,通過清理機制來保證我們數據不至於增長過快:

整體清理流程如下:

三、功能介紹

3.1 問題數據

3.1.1 TOP 問題列表

3.1.2 問題詳情

3.2 問題報警

3.3 性能報表

3.3.1 ANR 變化趨勢

3.3.2 慢方法變化趨勢

3.3.3 FPS 變化趨勢

 3.3.4 線程池卡頓次數

四、未來規劃

五、結語

通過性能監控的實踐以及後續的性能優化,幫助我們更好的解決了性能問題,總結下來它的核心價值在於:

性能監控與性能優化道阻且長,我們也會不斷地在這方面進行更多的嘗試和努力,爲 App 的穩定運行提供更好的保障,做好性能和穩定性的守門員。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/8PwGV9yrclaxiUA-0j65aA