偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

抖音 ANR 自動歸因平臺建設(shè)實踐

移動開發(fā)
抖音作為一個超大型的應(yīng)用,我們在 ANR 問題治理上面臨著很大的挑戰(zhàn)。

抖音作為一個超大型的應(yīng)用,我們在 ANR 問題治理上面臨著很大的挑戰(zhàn)。首先對于存量問題的優(yōu)化,由于缺少有效的歸因手段,一些長期的疑難問題一直難以突破解決,例如長期位于 Top 1 的 nativePollOnce 問題。同時我們在防劣化上也面臨很大的壓力,版本快速迭代引入的新增劣化,以及線上變更導(dǎo)致的激增劣化,都需要投入大量的人力去排查定位,無法在第一時間快速修復(fù)止損。

ANR 原理簡介

既然我們要建設(shè)的是 ANR 歸因平臺,首先需要了解下什么是 ANR ?它是 Android 系統(tǒng)定義的一種“應(yīng)用程序無響應(yīng)”的異常問題,目的是為了監(jiān)控發(fā)現(xiàn)應(yīng)用程序是否存在交互響應(yīng)慢或卡死的問題。從用戶的視角來看,發(fā)生 ANR 時設(shè)備上會出現(xiàn)提示應(yīng)用無響應(yīng)的彈窗,甚至在一些機(jī)型上可能就直接閃退了。所以 ANR 與其他崩潰問題一樣,是一種會對用戶體驗造成嚴(yán)重打斷的異常問題。

接下來我們從系統(tǒng)的設(shè)計原理來看下為什么會發(fā)生 ANR ?以一種常見的廣播超時引起的 ANR 為例,首先系統(tǒng) AMS 服務(wù)會通過 IPC 方式將一個有序廣播發(fā)送給應(yīng)用進(jìn)程,并在同時啟動一個超時監(jiān)控。應(yīng)用進(jìn)程在 Binder 線程接收到廣播之后,會將其封裝成一個消息 Message 加入到主線程的消息隊列里等待執(zhí)行。正常情況下,廣播消息在應(yīng)用內(nèi)都會得到及時響應(yīng),然后通知系統(tǒng) AMS 服務(wù)取消超時監(jiān)控。但是在一些異常的情況下,如果在系統(tǒng)設(shè)置的超時到來之前,目標(biāo)消息還沒有調(diào)度執(zhí)行完成的話,系統(tǒng)就會判定響應(yīng)超時并觸發(fā) ANR。

圖片

歸因方案現(xiàn)狀

當(dāng)前業(yè)界針對 ANR 問題的歸因手段有哪些?第一種是傳統(tǒng)歸因方案:基于系統(tǒng)生成的 ANR Trace 和 ANR Info 來定位問題原因。這里的 ANR Trace 是在問題發(fā)生時系統(tǒng)通知應(yīng)用自身 dump 采集的各個線程的堆棧以及狀態(tài)信息,而 ANR Info 中則包括了 ANR 原因、系統(tǒng)以及應(yīng)用進(jìn)程的 CPU 使用率 和 IO 負(fù)載等信息。對于像下圖中這類由于當(dāng)前消息嚴(yán)重耗時或卡死引起的 ANR,這種系統(tǒng)原生的方案可以幫助我們快速的定位到問題堆棧。

但是它也存在一個明顯的問題,從前面的原理分析可以知道,廣播等系統(tǒng)組件消息在加入到主線程之后,是按照它在消息隊列中的先后順序來執(zhí)行的,所以有可能是之前的歷史消息存在嚴(yán)重耗時從而引起的問題。這種情況下在 ANR 實際發(fā)生時系統(tǒng)抓取的堆棧很有可能就已經(jīng)錯過了問題的現(xiàn)場,基于這樣的數(shù)據(jù)進(jìn)行歸因得到的結(jié)果也是不準(zhǔn)確的。

圖片

第二種是慢消息歸因方案:通過監(jiān)控主線程消息的執(zhí)行情況,并結(jié)合耗時消息的采樣抓棧來定位問題原因。這個方案解決了前面?zhèn)鹘y(tǒng)歸因方案中存在的問題,提供了一種更細(xì)粒度的監(jiān)控和歸因能力,可以同時發(fā)現(xiàn)當(dāng)前和歷史的耗時消息,以及其中可能存在的耗時問題堆棧。

但這個方案也同樣存在的一些不足之處, 因為對于像抖音這樣的大型應(yīng)用來說,ANR 通常是由于各種復(fù)雜的綜合性因素導(dǎo)致的,包括子線程 / 子進(jìn)程 CPU 搶占、應(yīng)用 / 系統(tǒng)內(nèi)存不足等也都會對主線程的執(zhí)行效率造成影響,間接導(dǎo)致主線程整體都變慢了。在這種情況下,主線程的慢消息或堆??赡懿⒉皇菃栴}的根本原因,同樣以此得到的歸因結(jié)果也是不全面的。

圖片

所以總結(jié)一下目前的現(xiàn)狀,現(xiàn)有的 ANR 歸因方案存在以下幾個痛點問題:首先是歸因不準(zhǔn)確,歸因結(jié)果難以消費,不能真正解決問題。其次是歸因能力少,對于復(fù)雜問題難以定位根本原因。最后是歸因效率低,人工排查周期長。

建設(shè)思路

接下來重點介紹下 ANR 歸因平臺的建設(shè)思路,平臺歸因體系主要圍繞以下三個方向進(jìn)行建設(shè):

  • 單點問題歸因:首先需要對單個 ANR 問題實現(xiàn)精準(zhǔn)的歸因,這也是我們整個歸因體系建設(shè)的重點和基礎(chǔ)。
  • 聚合問題歸因:其次是線上大數(shù)據(jù)的聚合問題歸因,幫助我們聚焦 Top 重點問題。
  • 劣化問題歸因:最后線上灰度以及全量版本劣化問題的自動歸因,提升新增 / 激增問題的解決效率,目前正在建設(shè)中,本次分享就不展開介紹了。

單點歸因思路

單點 ANR 問題的歸因可以分為三個步驟,首先需要從原理出發(fā)明確 ANR 問題區(qū)間;接下來對問題進(jìn)行粗歸因,也就是一種定性的分析,比如說是主線程阻塞卡死、還是 CPU 搶占或是內(nèi)存異常導(dǎo)致的問題;最后就是進(jìn)一步進(jìn)行細(xì)歸因,也就是需要定位到具體的問題代碼,能實際指導(dǎo)我們消費并解決問題。

問題區(qū)間

首先從 ANR 問題的原理出發(fā),來分析一下如何大致確定 ANR 問題區(qū)間。我們同樣還是以上面的廣播消息超時引起的 ANR 為例,問題產(chǎn)生的時間順序為:從系統(tǒng) AMS 服務(wù)發(fā)送有序廣播并啟動超時監(jiān)控開始,到應(yīng)用進(jìn)程將該廣播消息加入到主線程消息隊列,并按照隊列中的先后順序等待調(diào)度執(zhí)行。當(dāng)系統(tǒng)進(jìn)程的超時時間結(jié)束前,對應(yīng)的廣播消息還沒有執(zhí)行完成并通知系統(tǒng),系統(tǒng)就會判定響應(yīng)超時并觸發(fā) ANR。這里我們可以以 ANR 實際發(fā)生時間為結(jié)束點,往前回溯對應(yīng)的超時時間(這里不同的 ANR 原因會對應(yīng)不同的超時時間設(shè)置),也就是后續(xù)需要診斷分析 ANR 問題區(qū)間范圍。

圖片

粗歸因

在明確 ANR 問題的時間范圍后,我們需要從技術(shù)角度來拆解下,如何進(jìn)行粗歸因的定性分析。從上面的原理分析可以推導(dǎo)出,引起 ANR 的根本原因就是系統(tǒng)組件消息(包括 input 事件)在應(yīng)用側(cè)沒有得到及時的執(zhí)行。而我們知道這些關(guān)鍵目標(biāo)消息都是在主線程中進(jìn)行消費處理的,所以這里的關(guān)鍵點就是 ANR 區(qū)間內(nèi)之前的這些消息為什么執(zhí)行耗時 ?從系統(tǒng)的角度來看,所有代碼邏輯的執(zhí)行可以分為 On-CPUOff-CPU 兩種情況:

  • On-CPU:對應(yīng) Running 狀態(tài),即當(dāng)前任務(wù)正在占用 CPU 資源進(jìn)行計算處理。已知 計算耗時 = 計算量 / 計算速度,這里計算速度會受到 CPU 硬件本身的限制,比如 CPU 核心頻率以及當(dāng)前運行在大核或小核上。另一個跟應(yīng)用自身關(guān)系比較緊密的就是計算量,例如主線程在執(zhí)行 CPU 密集型的操作,比如 JSON 序列化 / 反序列化,或是在處理大量的高頻業(yè)務(wù)消息。
  • Off-CPU:包括 Runnable 和 Sleep 兩種狀態(tài)。Runnable 代表任務(wù)所需的資源已就緒,正在 CPU 運行隊列上等待調(diào)度執(zhí)行,這里除了受到系統(tǒng)本身的調(diào)度策略的影響之外,也跟當(dāng)前同樣已就緒并等待調(diào)度的任務(wù)數(shù)量有關(guān)。如果子線程或子進(jìn)程有很多 CPU 耗時任務(wù)在等待執(zhí)行的話,因為總的計算資源是有限的,互相之間頻繁的搶占也會影響主線程的執(zhí)行效率。Sleep 代表任務(wù)在阻塞等待資源,比如等待 Lock、IO、同步 Binder 以及內(nèi)存 Block GC 等。通常情況下我們應(yīng)該避免在主線程發(fā)生這類 Block 阻塞問題,同時這也是比較常見的一類解決卡頓或 ANR 的優(yōu)化手段。

圖片

下面我們來看下第一種主線程異常消息直接引起的 ANR,它可能是由于當(dāng)前消息嚴(yán)重耗時或卡死導(dǎo)致的,也可能是由于之前的一個或多個歷史耗時消息引起的 ANR。

圖片圖片

第二種就是后臺任務(wù) CPU 資源搶占引起的ANR,它會間接影響主線程的執(zhí)行效率。從下圖中可以看到在子線程 CPU 負(fù)載變高之后,主線程的整體性能開始下降變慢,這種情況下就會更容易發(fā)生 ANR。最典型的就是在冷啟動的場景下,通過降級或打散 CPU 耗時的后臺任務(wù),我們已經(jīng)驗證可以有效的降低 ANR 率以及縮短啟動首刷耗時。

圖片

最后一種內(nèi)存等資源異常問題,例如虛擬機(jī) Java 內(nèi)存不足時,GC 線程就會開始變得活躍并進(jìn)行頻繁 GC,這同樣也會搶占主線程 CPU 資源或 Block GC 等待,從而導(dǎo)致 ANR 問題的發(fā)生。對于抖音這樣的視頻類大型應(yīng)用,線上內(nèi)存問題導(dǎo)致的卡頓或 ANR 問題的占比較高,目前也在專項治理優(yōu)化中。

圖片

基于以上的演繹推理,總結(jié)一下我們的歸因思路主要包括以下幾類:第一,主線程本身的異常問題,例如存在嚴(yán)重的阻塞等待或者 CPU 繁忙等問題。第二,后臺任務(wù)搶占 CPU 資源導(dǎo)致的異常問題。最后,內(nèi)存 / IO 等系統(tǒng)資源不足導(dǎo)致的異常問題,目前正在探索中,本次分享就不展開介紹了。

細(xì)歸因

主線程消息異常

首先來看主線程消息異常的歸因思路:我們需要先對主線程消息進(jìn)行監(jiān)控,這里包括三種情況,已經(jīng)執(zhí)行完成正在執(zhí)行中的消息以及消息隊列中待執(zhí)行的消息。對于已經(jīng)或正在執(zhí)行的消息,我們主要關(guān)注它們的耗時情況,通過分析系統(tǒng)源碼我們可以知道,主線程消息隊列里處理的消息一共包括三種:Java 消息、Native 消息和 Idle Handler。而對于待執(zhí)行的消息,我們主要關(guān)注其中的數(shù)量,從而判斷是否存在大量消息堆積的異常問題。

圖片

對于主線程異常消息的問題類型,第一類就是耗時消息,即在問題區(qū)間內(nèi)存在一個或多個耗時大于閾值的慢消息。另一種是高頻消息,也就是存在出現(xiàn)次數(shù)以及累計耗時超過一定閾值的高密度消息。這里通過對業(yè)務(wù)消息的 target、callback 和 what 等信息進(jìn)行聚合分析,有時也可以協(xié)助定位到導(dǎo)致問題的業(yè)務(wù)方。

圖片圖片

但是僅僅找到異常消息并不能直接幫助我們解決問題,還需要對消息的耗時原因做進(jìn)一步的歸因分析,找到其中引起消息耗時的問題函數(shù)。接下來介紹一下線上 Trace 數(shù)據(jù)采集方案,這里我們采取類似 Matrix 方案,通過 ASM 字節(jié)碼工具,在編譯時對應(yīng)用內(nèi)的業(yè)務(wù)代碼進(jìn)行插樁,也就是在函數(shù)的入口和出口插入一行統(tǒng)計代碼,來記錄當(dāng)前方法的運行耗時。為了降低采集時的性能損耗,將方法 begin / end 狀態(tài)標(biāo)識、當(dāng)前方法 ID 以及時間戳的 Diff 相對值,合并使用一個 64 位的變量來記錄。在 ANR 等異常問題發(fā)生時,再將 Ring Buffer 中記錄的數(shù)據(jù)進(jìn)行上報,在后端數(shù)據(jù)鏈路處理生成對應(yīng)的 Trace 堆棧,并提供給后續(xù)的診斷算法進(jìn)行自動化分析,以及 Perfetto 人工可視化分析的需求。

圖片

但對于抖音這樣的大型應(yīng)用來說,插樁方案也會有一些弊端,當(dāng)插樁的函數(shù)過多時,會對包體積以及性能產(chǎn)生負(fù)面的影響。為了盡可能降低監(jiān)控工具對線上用戶體驗的影響,我們提出了精準(zhǔn)插樁的方案!因為結(jié)合對于線上問題的分析訴求來看,我們重點關(guān)注的是上層執(zhí)行的業(yè)務(wù)函數(shù),比如頁面生命周期、業(yè)務(wù)消息等入口方法,以及底層那些可能耗時的業(yè)務(wù)函數(shù)。所以我們基于靜態(tài)代碼分析的基礎(chǔ)能力,分析提取出帶有耗時特征的函數(shù)來進(jìn)行插樁,例如下面表格中帶有鎖關(guān)鍵字的函數(shù)、存在 Native / IO 等調(diào)用的函數(shù)以及特別復(fù)雜的大方法等。在這個精準(zhǔn)插樁的優(yōu)化策略之下,大幅減少了約 90% 的插樁數(shù)量!

圖片

在大幅精簡插樁數(shù)量之后,我們在消費線上數(shù)據(jù)時又面臨到一個問題,就是僅有插樁的堆棧信息太少,有時難以幫助我們實際定位到發(fā)生問題的代碼。為了解決這一痛點問題,我們又設(shè)計了插樁和抓棧數(shù)據(jù)擬合的優(yōu)化方案,其原理就是通過對耗時超過一定閾值的慢函數(shù)進(jìn)行抓棧上報,然后在服務(wù)端再將插樁與抓棧數(shù)據(jù)根據(jù)時間點進(jìn)行擬合,補齊其中缺失的業(yè)務(wù)和系統(tǒng)堆棧信息。如下圖中所示,當(dāng)插樁堆棧中連續(xù)兩個節(jié)點能在抓棧數(shù)據(jù)中找到最小間距的數(shù)據(jù)并對齊時,抓棧數(shù)據(jù)中對應(yīng)層之間的數(shù)據(jù)將會被補全到到插樁數(shù)據(jù)中,生成新的擬合堆棧數(shù)據(jù),圖中的 D 就是被補全的數(shù)據(jù)。

圖片圖片

在獲取到線上問題發(fā)生時的詳細(xì) Trace 數(shù)據(jù)后,我們需要進(jìn)一步找到其中引起耗時的問題函數(shù),常見的問題函數(shù)類型包括以下兩種:

  • 慢函數(shù):是指函數(shù)的執(zhí)行耗時超過一定的閾值;并且從實際可消費性的角度來看,我們預(yù)期是要能找到更靠近葉子節(jié)點的業(yè)務(wù)慢函數(shù)。所以需要根據(jù)實際調(diào)用堆棧的情況,進(jìn)一步剔除底層的基礎(chǔ)庫或工具類方法,以及存在相同調(diào)用鏈路的親緣父子節(jié)點,來找到最合適的慢函數(shù)問題。
  • 高頻函數(shù):對應(yīng)就是單個雖然并不耗時,但是由于次數(shù)很多,累計執(zhí)行耗時超過閾值的函數(shù);根據(jù)我們以往的經(jīng)驗來看,對于高頻函數(shù)的優(yōu)化通常也能帶來不錯的收益。

圖片圖片

當(dāng)然僅僅知道函數(shù)慢也是不夠的!我們結(jié)合一個線上實際的示例來看,通過 Trace 可以發(fā)現(xiàn)標(biāo)記紅框的這里有一個業(yè)務(wù)函數(shù)執(zhí)行比較耗時,但是這里為什么會耗時呢?我們要如何進(jìn)行優(yōu)化呢?目前僅有的堆棧信息并不能滿足我們的歸因需求。之后通過分析業(yè)務(wù)代碼并補齊了缺失的“關(guān)鍵”信息之后,我們就可以明確知道這里耗時的原因是由于鎖競爭導(dǎo)致的,并且我們還進(jìn)一步補充了當(dāng)前持有鎖的線程以及堆棧等重要信息。

圖片圖片

為了更好的對慢函數(shù)的耗時進(jìn)行歸因,除了前面采集的 Trace 堆棧數(shù)據(jù)之外,我們還需要補充一些關(guān)鍵的上下文信息,這里就統(tǒng)稱為精細(xì)化數(shù)據(jù)。比如上面提到的鎖,還有函數(shù)的 CPU-Time、Binder 調(diào)用的名稱、IO 讀寫的文件路徑和大小、繪制渲染相關(guān)的 RenderNode,以及內(nèi)存 Block GC 等相關(guān)信息。

圖片

所以回顧總結(jié)一下主線程消息異常的歸因流程,首先需要明確當(dāng)前 ANR 的問題區(qū)間,然后找到其中的異常消息(耗時消息或高頻消息),進(jìn)一步下鉆找到其中引起耗時的問題函數(shù)(慢函數(shù)或高頻函數(shù)),最后再結(jié)合精細(xì)化數(shù)據(jù)對其耗時原因進(jìn)行歸因。

圖片

后臺任務(wù)異常

接下來再看下后臺任務(wù) CPU 異常的歸因思路:首先我們需要明確是否存在后臺任務(wù)對主線程 CPU 資源產(chǎn)生搶占的問題,這里可以結(jié)合主線程的非自愿上下文切換以及調(diào)度狀態(tài)的信息,來觀測主線程是否有較多的時間都花費在等待系統(tǒng)調(diào)度上。如果存在明顯的異常情況,再結(jié)合系統(tǒng)和應(yīng)用的 CPU 使用率信息,可以進(jìn)一步先定位到是應(yīng)用的子線程 / 子進(jìn)程,或是關(guān)鍵系統(tǒng)進(jìn)程(如 dex2oat 進(jìn)程等),還是其他應(yīng)用進(jìn)程造成的 CPU 資源搶占。

對于應(yīng)用自身造成的 CPU 搶占問題,我們需要進(jìn)一步定位到具體的問題代碼。所以我們在之前的 Trace 采集方案的基礎(chǔ)上,進(jìn)行了重大的升級改造,擴(kuò)展支持了全線程的 Trace 數(shù)據(jù)采集。

圖片


單線程 Trace

多線程 Trace

說明

Flag 狀態(tài)位

2 bit

2 bit

代表函數(shù)開始/結(jié)束:3(二進(jìn)制0b11)= catch, // 預(yù)留 2(二進(jìn)制0b10)= throw,// 預(yù)留 1(二進(jìn)制0b01)= begin, 0(二進(jìn)制0b00)= end

Method ID

20 bit

20 bit

代表插樁的方法 ID,最大支持 1048575 個函數(shù)

Thread ID

-

15 bit

代表當(dāng)前線程的 TID

Timestamp

42 bit

27 bit

代表當(dāng)前函數(shù)執(zhí)行時與基準(zhǔn)時間的相對時間,多線程模式下最大支持 134,217,727 ms = 約 1.5 天

由于后臺任務(wù)我們重點關(guān)注的是 CPU-Time 耗時,所以在采集函數(shù)的 Wall-Time 執(zhí)行耗時之外,同時也支持函數(shù)粒度的 CPU-Time 耗時采集,并在后端進(jìn)行處理關(guān)聯(lián)。這里出于性能損耗上的考慮,我們會進(jìn)一步精簡控制同時需要采集 CPU 時間的插樁函數(shù)數(shù)量,例如僅對系統(tǒng)的生命周期方法,以及子線程的 Runnable、Callable 以及二方 / 三方的任務(wù)框架入口方法,以及少量的關(guān)鍵特征方法才開啟,并且會設(shè)置最小的采樣間隔時間。

對于 CPU-Time 的獲取一般有兩種方式:一種是通過定期讀取 proc 文件系統(tǒng)下的文件來解析獲取,這種方式如果想要精確到方法級別需要相當(dāng)高的讀取頻率,這種高頻率讀取文件并解析的性能損耗很高,不適合在線上方法級別的 CPU-Time 采集;另一種則是通過 Android 提供的 SystemClock.currentThreadTimeMillis() 方法或者 Native 層的 clock_gettime(CLOCK_THREAD_CPUTIME_ID) 方法獲取當(dāng)前線程的 CPU-Time,這種方式比較適合采集方法級別的 CPU 耗時,在方法開始和結(jié)束時分別調(diào)用前述方法再計算差值即可,因此我們線上采集選擇的也是這個方案。

同樣回顧總結(jié)一下后臺任務(wù)異常的歸因流程,在 ANR 的問題區(qū)間內(nèi),首先需要明確是否存在對主線程執(zhí)行效率產(chǎn)生明顯影響的 CPU 資源搶占,如果是應(yīng)用自身的問題,先找到應(yīng)用內(nèi) CPU 負(fù)載較高的線程或進(jìn)程,進(jìn)一步定位到對應(yīng)異常階段里的后臺任務(wù)代碼,最后再結(jié)合精細(xì)化數(shù)據(jù)對其 CPU 耗時原因進(jìn)行歸因。

圖片

聚合歸因思路

基于以上對 ANR 單點問題進(jìn)行診斷分析后產(chǎn)出的歸因結(jié)論,我們可以進(jìn)一步結(jié)合線上大數(shù)據(jù)進(jìn)行聚合歸因,從而幫助我們更好的聚焦到 Top 重點問題的優(yōu)化上。

歸因標(biāo)簽

首先是對歸因標(biāo)簽的聚合分析,主要包括以下幾類:

  • 粗歸因標(biāo)簽:針對 ANR 問題定性的歸因分類標(biāo)簽,包括主線程阻塞、高頻消息、CPU 搶占、堆內(nèi)存不足等。
  • 細(xì)歸因標(biāo)簽:針對細(xì)歸因定位到的問題代碼的精細(xì)化歸因標(biāo)簽,包括主線程鎖、IO、Binder 或者 Block GC 阻塞耗時等。
  • 業(yè)務(wù)歸因特征:發(fā)生 ANR 時用戶所在場景頁面等業(yè)務(wù)維度的特征標(biāo)簽,有時也可以輔助快速定位到問題相關(guān)的業(yè)務(wù)方。

如下圖所示,通過對以上不同歸因標(biāo)簽的多維聚合分析,可以幫助我們對線上 ANR 問題的特征分布有一個全局的了解和認(rèn)知,同時也能指導(dǎo)我們在歸因能力上下一步需要重點攻堅的方向。

圖片

異常問題

其次是對細(xì)歸因產(chǎn)出的異常問題進(jìn)行聚合分析, 目前主要包括主線程異常函數(shù)、后臺任務(wù)以及內(nèi)存這三個維度。聚合后的問題列表支持滲透率、耗時均值、PCT 50 / 90 耗時以及場景等維度的統(tǒng)計數(shù)據(jù),可以幫助我們識別出線上整體占比較高或耗時特別嚴(yán)重的這類問題。

圖片

在進(jìn)入異常函數(shù)的歸因詳情頁之后,可以查看當(dāng)前問題函數(shù)在線上大數(shù)據(jù)聚合后的火焰圖,其中 Caller 堆棧代表上層不同業(yè)務(wù)方的調(diào)用次數(shù)分布情況,而 Callee 堆棧則是所有子函數(shù)的耗時分布情況。

圖片圖片

最后,基于以上的歸因標(biāo)簽、異常問題以及業(yè)務(wù)歸因信息,平臺會產(chǎn)出一個對 ANR 問題最終的歸因結(jié)論以及對應(yīng)的綜合置信度評分。

圖片

落地效果

接下來再介紹一下平臺目前的落地效果:首先這個案例是一個啟動階段的 ANR 問題,我們從主線程 Trace 中可以分析定位到主線程的耗時函數(shù),并且通過細(xì)歸因標(biāo)簽的結(jié)果,可以明確知道是一個鎖耗時的問題。進(jìn)一步結(jié)合鎖的詳情信息進(jìn)行下鉆分析,通過當(dāng)前子線程持有鎖的聚合堆棧,發(fā)現(xiàn)是由于某個后臺任務(wù)的執(zhí)行時機(jī)變更提前了,從而與主線程某個任務(wù)產(chǎn)生了鎖競爭沖突,導(dǎo)致主線程長時間的阻塞等待引起了 ANR。

圖片

圖片圖片

第二個案例是一個主線程高頻消息問題,從定位到的問題函數(shù)可以發(fā)現(xiàn)其調(diào)用的非常高頻,平均在一次 ANR 里會出現(xiàn)了上千次!通過進(jìn)一步分析發(fā)現(xiàn)是由于某個業(yè)務(wù)的邏輯 Bug,導(dǎo)致在特定場景下會發(fā)送大量的重復(fù)消息,導(dǎo)致主線程消息隊列堵塞引起的 ANR 劣化。

圖片圖片

第三個案例是一個子線程高頻任務(wù)問題,通過定位到的后臺任務(wù)可以發(fā)現(xiàn)其在多個子線程的出現(xiàn)次數(shù)都非常高頻,并且累計的 CPU 耗時也比較高。進(jìn)一步分析發(fā)現(xiàn)也是某個業(yè)務(wù)的 Bug 問題,在特定場景下會向子線程發(fā)送大量的重復(fù)任務(wù),并且由于這些異步任務(wù)內(nèi)部還會給主線程 Handler 發(fā)送或刪除消息,所以除了會搶占 CPU 資源之外,還會間接導(dǎo)致主線程消息隊列在遍歷取消息時會發(fā)生高頻的鎖競爭耗時,兩個因素疊加之下引起的 ANR。

圖片圖片

最后總結(jié)下平臺過去一年的階段性成果,總共累計發(fā)現(xiàn)了有效問題 88 個,修復(fù)并優(yōu)化其中 56 個,同時協(xié)助抖音 / 抖極的大盤 ANR 率分別下降了 -13.06%-8.70% ,并取得了不錯的業(yè)務(wù)收益。

總結(jié)展望

抖音 ANR 自動歸因平臺未來的規(guī)劃主要包括以下三個方面:

  • 歸因體系:持續(xù)打磨監(jiān)控能力和歸因算法,包括探索完善 Java / Native 內(nèi)存、繪制渲染以及 Native Trace 等方向上的精細(xì)化歸因能力。
  • 防劣化體系:持續(xù)優(yōu)化線上劣化歸因和消費流程,提升線上自動歸因準(zhǔn)確率,以及劣化問題的消費解決效率。
  • 專家系統(tǒng):沉淀專家經(jīng)驗,并嘗試結(jié)合大模型等新技術(shù),通過對技術(shù)特征和業(yè)務(wù)特征進(jìn)行精細(xì)化聚合分析,進(jìn)一步提升問題發(fā)現(xiàn)和解決效率。
責(zé)任編輯:龐桂玉 來源: 字節(jié)跳動技術(shù)團(tuán)隊
相關(guān)推薦

2024-10-31 08:22:56

2022-06-06 12:19:08

抖音功耗優(yōu)化Android 應(yīng)用

2024-06-13 17:10:16

2022-08-26 16:24:19

抖音體系化建設(shè)項目

2022-07-20 22:55:39

直播OOM抖動

2024-07-18 08:33:19

2022-03-29 13:27:22

Android優(yōu)化APP

2023-11-03 17:02:18

抖音直播畫質(zhì)優(yōu)化

2019-08-16 11:48:53

容器云平臺軟件

2023-03-03 15:43:23

抖音世界杯畫質(zhì)優(yōu)化

2022-06-23 11:19:14

抖音春節(jié)發(fā)券

2022-12-29 09:13:02

實時計算平臺

2023-02-28 07:01:11

分布式緩存平臺

2023-03-28 08:28:34

2021-06-28 05:19:32

抖音電腦

2017-12-10 20:53:56

Docker持續(xù)交付容器

2023-01-27 19:33:10

消息中心管理平臺

2023-06-05 07:36:30

數(shù)據(jù)湖大數(shù)據(jù)架構(gòu)

2018-06-05 10:54:06

點贊
收藏

51CTO技術(shù)棧公眾號