闲鱼如何建设技术舆情治理体系 (多图多代码)
簡介: 從日志、監控、性能檢測幾個方面建設了有日志可查、有數據可依的排查體系
現狀和問題
?
閑魚的輿情治理,依托阿里集團的設施建設,有以下能力:
- 崩潰異常、性能在線聚合查詢;
- 本地日志:TLog;
- 在線日志:埋點日志(t+1)和用戶行為日志(路徑和請求)
但在應對輿情治理方面仍存在較多的問題:
- 有相當一部分閃退、黑屏、卡死輿情無 Crash 或 ANR 日志;
- 技術輿情中的業務問題定位困難;業務問題如圖片視頻上傳失敗、內容顯示異常、無法退出、服務器錯誤等;日志內容缺失:大部分業務日志被寫入控制臺,而不是本地日志或在線日志;個別重要業務使用埋點日志,但仍可能存在內容不足和 t+1 不及時問題。
- 本地日志定位問題能力有限本地 TLog 日志有較為詳細的集團二方 SDK 日志,但缺失設備基礎信息、業務日志、用戶行為日志等未知異常問題,如視頻綠屏等,無控制臺 logcat 日志日志規范不完善,日志查看效率低
- 本地日志回撈困難用戶主動反饋時,沒有觸發本地日志上報閑魚屬于交易 App,用戶不會長時間在線,在線命令推送成功率低命令推送在后臺沒有緩存機制
- 反饋問題和線上實際情況存在偏差閑魚反饋入口較深,相比閑魚上億用戶基數,反饋占比低,存在線上有問題但無反饋的情況
輿情治理方案整體設計
基于現狀問題,重新梳理和補充的輿情治理體系如下圖:
基于現狀問題,重新梳理和補充的輿情治理體系如下圖:
?
線上輿情問題治理體系
下面會重點展開講述的內容:
- 如何提升本地日志定位能力
- 補充線上卡頓監測能力
- 補充主動發現問題能力
提升本地日志定位能力
本地控制臺日志補充
治理前期,大量業務日志進入了控制臺日志,即便治理后將大量日志轉入 tlog 日志,仍有部分日志流入控制臺,如 Android Maven 引入獨立模塊和 Flutter 插件包模塊。此外,部分未知異常問題,如視頻綠屏、黑屏等,logcat 日志也提供了定位的可能性。
Android Log 模塊提供了多種日志緩存類型,見 Android logging,可通過 logcat 命令獲取對應類型的日志。這里,我們在用戶反饋的時候,分別將 LOG_ID_MAIN、LOG_ID_EVENTS 和 LOG_ID_CRASH 類型 logcat 讀取并寫入到本地文件,而后將 logcat 日志同 tlog 文件一起打包通過 AUS 上傳至 OSS。
// LOG_ID_MAIN 主應用程序log,-t 設置日志上限 20000 adb logcat -d -v threadtime -t 20000// LOG_ID_EVENTS 系統事件信息 adb logcat -d -b events -v threadtime -t 6666// LOG_ID_CRASH 應用程序 crash 日志 adb logcat -d -b crash -v threadtime -t 6666?
logcat.txt 內容
本地日志回撈能力
前面提到,由于在線命令推送成功率低且后臺無命令緩存機制,所以閑魚 App 本地日志回撈困難。為解決日志難以獲取問題,輿情治理體系中設計了多種日志回撈策略,見下圖所示。
?
本地日志回撈策略
?
本地日志下載查看流程
- 為提升用戶主動反饋觸發的日志上傳成功率,使用 AUS 上傳日志打包文件至 OSS 平臺,同時將 url 寫入反饋內容(打包和上傳若超出5秒則無法寫入反饋內容)和阿里云 SLS 實時日志平臺;
- 為提升研發下載本地日志的效率,使用 TLog SDK 上傳至 TLog 平臺,其中 50% 以上能上傳成功。
線上卡頓/ANR檢測能力
線上用戶反饋 ANR 并給出截圖證明,因為沒有卡頓日志,難以定位問題。
?
線上用戶反饋黑屏,無有效日志難以定位問題
頁面卡死的另一種表現
技術方案現狀
在閑魚 App 的混合工程場景,依托 Emas 平臺已實現 iOS 端卡頓檢測,Flutter 端卡頓檢測方案查看 Flutter卡頓問題的監控與思考,這節主要講述 Android 端線上卡頓/ANR 檢測。
在線下場景,Android 端卡頓/ANR 檢測手段已經很成熟,普通卡頓檢測方案有 BlockCanary,ANR 檢測可通過 adb bugreport 查看 traces.txt 文件得到。然而在線上環境,以上卡頓檢測方案就存在一定問題。
traces.txt 文件權限問題
在線上場景,為了監聽識別是否發生 ANR 以及讀取 ANR 內容,APP 需要監聽 traces.txt 文件變化,并嘗試讀取 traces.txt 文件內容。監聽文件的方案,在 Android 6.0 及以后存在權限問題,大部分場景無法檢測到 ANR
- 無法訪問 /data/anr/traces.txt 文件
- 無法讀取有效系統屬性 dalvik.vm.stack-trace-file
如以下代碼執行在紅米手機 Android 11 上運行,mSystemTraceFilePath 為 "",mSystemTraceFile 的路徑為 "/"
File mSystemTraceFile;... this.mSystemTraceFilePath = "/data/anr/traces.txt"; this.mSystemTraceFile = new File(this.mSystemTraceFilePath); if (!this.mSystemTraceFile.exists()) {String propSystemTraceFilePath = SystemPropertiesUtils.get("dalvik.vm.stack-trace-file");...this.mSystemTraceFile = new File(propSystemTraceFilePath);... } ...BlockCanary 檢測原理和性能問題
核心原理
?
BlockCanary 檢測 500ms 卡頓
BlockCanary 的核心原理是,設置 UI 線程的 Looper.mLogging 字段,主線程每次處理消息均會執行 print 方法。
public void start() {if (!mMonitorStarted) {mMonitorStarted = true;Looper.getMainLooper().setMessageLogging(mBlockCanaryCore.monitor);} }BlockCanary.java
public void setMessageLogging(@Nullable Printer printer) {mLogging = printer; }public static void loop() {...for (;;) {...// This must be in a local variable, in case a UI event sets the loggerfinal Printer logging = me.mLogging;if (logging != null) {logging.println(">>>>> Dispatching to " + msg.target + " " +msg.callback + ": " + msg.what);}...} }Looper.java
在 print 方法中時,觸發 StackSampler 工作,即取消上一次異步線程延遲任務,重新觸發一次延遲任務,延遲時間為 BlockThreshold * 0.8f (假設要檢測 500ms 以上的卡頓堆棧,則延遲時間為 400ms)。若 UI Looper 任務發生卡頓(>BlockThreshold),則延遲任務被執行,且在卡頓期間的獲取主線程堆棧信息,之后在下一次 print 方法被執行的時候,若確認發生卡頓,則可把主線程堆棧信息當做卡頓堆棧記錄上報。
@Override public void println(String x) {...if (!mPrintingStarted) {mStartTimestamp = System.currentTimeMillis();mStartThreadTimestamp = SystemClock.currentThreadTimeMillis();mPrintingStarted = true;startDump();} else {final long endTime = System.currentTimeMillis();mPrintingStarted = false;if (isBlock(endTime)) {notifyBlockEvent(endTime);}stopDump();} }LooperMonitor.java
性能問題
在線上環境,大部分場景下并不會發生卡頓,但卡頓檢測 SDK 會一直執行。可以發現 app 每一幀時間(16.6ms),UI Looper 中的任務會執行多次,最終產生大量的無效字符串拼接操作和大量小對象碎片。特別的,在線上低端機或者 cpu 負載較高的場景下,app 性能會因此降級,影響用戶體感。
logging.println(">>>>> Dispatching to " + msg.target + " " +msg.callback + ": " + msg.what);卡頓檢測方案
方案設計
針對 traces.txt 讀取權限問題,可通過檢測主線程 5s 卡頓當做 anr。針對 BlockCanary 線上使用的性能問題,為降低延遲任務取消和觸發頻率,同時避免字符串對象頻繁創建問題,必須放棄 Looper.mLogging 的方案。重新思考為什么可以通過設置 Looper.mLogging 檢測卡頓?其滿足 2 個條件:
- 若主線程方法執行發生卡頓,則 Looper Task 執行時長變長
- 可通過 Looper.mLogging 監聽每個 Task 執行時長
閑魚線上使用 Android 幀回調代替 Looper Task 方案,同時滿足以上 2 個條件:
- 若主線程方法執行發生卡頓,則幀回調間隔時長變長
- 可通過注冊幀回調監聽每幀時長
此外,為避免 BlockCanary 方案延遲任務觸發和取消的頻率過高的問題,僅在幀回調處記錄時間戳,不再取消延遲任務,但在延遲任務執行時判斷是否發生卡頓,同時記錄主線程堆棧。
假設 500ms 以上為卡頓,整體方案流程圖如下:
- 無卡頓場景
- ?
- 卡頓場景
- ?
- 僅在頻繁觸發的幀回調處,記錄時間戳,無性能消耗
- 避免延遲任務觸發和取消的頻率過高的問題,500ms(卡頓閾值) 最多執行 2 次延遲任務
- 不再取消延遲任務
- 在任務執行時,判斷當前時間和上一幀時間戳時間差。僅在發生卡頓時,dump 主線程堆棧
定義 5s 以上卡頓為 ANR,為檢測 ANR,同樣通過 500ms 卡頓檢測,并做卡頓堆棧聚合,當連續發生卡頓大于 5s 且堆棧信息不變,則認為發生 ANR。發生 ANR 時,記錄當前設備 CPU 負載等信息。
檢測效果
閑魚首頁卡片點擊事件中故意制造 500ms 和 5s 卡頓查看卡頓檢測結果。
// CardView61801.javaprivate void doOnClick(String redirectUrl, Map<String, String> trackParams) {if (null == mCardBean) return;try {Thread.sleep(500);// Thread.sleep(5000);} catch (Exception e) {e.printStackTrace();}... }查看檢測結果
- Sleep 500ms
- ?
- Sleep 5s
- ?
小結
以上是閑魚 Android 線上卡頓檢測方案,線上已經運行超過 3 個版本,通過日志可發現用戶反饋卡死、無反應、閃退、黑屏等現象都有可能是 ANR 造成。整體方案有以下特點:
- 線上卡頓檢測無性能問題
- 以 5s 以上卡頓當做 ANR
- 相比 BlockCanary Looper Task 在 0.8*卡頓閾值 時獲取卡頓堆棧,本方案 500ms 卡頓檢測有更高概率獲取錯誤堆棧。但通過連續卡頓堆棧比對,可確保 5s 卡頓堆棧的準確性。而 500ms 卡頓通過線上統計提升準確性若業務需要,必須提升 500ms 單次卡頓堆棧準確率,可簡單修改方案:判斷大于 250ms 獲取一次卡頓堆棧,2 次連續相同卡頓堆棧且卡頓時長大于 500ms 作為最終卡頓判斷
主動發現問題能力
由于閑魚 App 反饋入口較深,因此相比上億用戶而言,每日技術輿情反饋量占比偏低,以此可知技術輿情反饋量并不能準確反應線上質量情況。為此,我們通過監控埋點構建線上關鍵輿情問題和基礎性能大盤,同時通過監控大盤主動發現線上重點待解決問題,加速線上輿情收斂速度和質量提升,流程圖如下所示。
?
主動發現問題流程圖
監控大盤
?
主動發現問題大盤示例
- 業務輿情問題大盤
- 通過統計一段時間的輿情問題,得到關鍵輿情問題,以此添加監控埋點并構建線上報表。通過大盤數據得到線上問題發生量和重要歸因,通過重點解決排名前幾的歸因,達到輿情問題快速收斂的目的。
- 基礎問題
- 除了 Crash、Flutter異常、性能等線上大盤,我們構建了 5s 卡頓監控、網絡請求失敗、慢請求、錯誤 toast 等基礎監控大盤。
監控問題定位
基于大盤發現了問題,需要獲取對應日志來定位問題,但問題對應的用戶很可能并不會反饋輿情或反饋內容不是該問題,為此我們構建了實時日志查詢以及本地日志批量回撈能力。
實時日志查詢平臺
?
自建輿情追蹤平臺
針對關鍵監控問題,客戶端增加對應的 SLS 實時日志,在自建輿情追蹤平臺獲取用戶的在線日志。平臺支持用戶名和時間查詢,同時支持用戶行為、用戶異常、輿情日志類型的組合查詢。
本地日志批量回撈能力
在線日志難以避免日志內容不足的問題,如基礎日志、其他關鍵模塊日志等,然而單個用戶的本地日志回撈成功很低(原因見上文內容),為此構建輿情日志回撈平臺,通過批量回撈的方式確保能獲取到輿情問題某個用戶的本地全量日志。
- 輸入輿情 IssueName 查詢用戶 id
- 批量回撈結果查詢
- ?
總結和展望
經過治理,整體線上技術類輿情占比從 10.5% 降低至 4.7%;基于主動發現問題和解決重點問題,每日上傳圖片失敗數從 10W+ 次降低至小于 7K+ 次,其他數據不再羅列。
初步建立的閑魚輿情治理體系如下所示:
- 日志類型:本地日志和在線日志;
- 在線日志:實時在線 SLS 日志,用戶行為日志,埋點(t+1)日志,高可用 SDK 日志(崩潰異常、白屏、性能);
- 日志查詢:提供日志規范和日志過濾文檔提供查詢效率;
- 日志內容:基礎日志和業務日志;
- 基礎日志:logcat 日志,卡頓/ANR日志,高可用 SDK 日志(crash、異常等),設備信息、賬號信息等;
- 日志回撈:反饋時主動上傳(TLog平臺和OSS平臺),在線命令回撈(含TLog平臺回撈,自建消息通道回撈);
- 問題發現:用戶反饋問題和主動發現問題
- 反饋入口:普通客服反饋和灰度截屏反饋特別的,MIUI 系統下的截屏事件可監聽廣播 miui.intent.TAKE_SCREENSHOT
此外,未來仍有很大的演進空間如下:
- 日志可視化日志語義化描述展示用戶行為、內存、CPU、流量等可視化閑魚用戶本地日志手動解析后的內存可視化舉例
- 日志智能解析關鍵日志和歷史問題關聯形成知識庫
- 關鍵日志反向回撈用戶日志類似主動發現問題場景中的回撈能力,可根據配置下發或其他關鍵在線日志回撈用戶日志
- 日志關聯聚合查詢基于用戶和時間,聚合服務端、前端、客戶端日志,聚合多種在線和本地日志。
作者:閑魚技術——云從
原文鏈接
本文為阿里云原創內容,未經允許不得轉載
總結
以上是生活随笔為你收集整理的闲鱼如何建设技术舆情治理体系 (多图多代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Fluid给数据弹性一双隐形的翅膀 (1
- 下一篇: 如何在Spring生态中玩转Rocket