ANR监控方案总结

作者: ModestStorm | 来源:发表于2022-09-10 17:59 被阅读0次

1.前言

ANR比较棘手在于,没有崩溃日志,定位问题比较困难,而且ANR是必须要解决的问题。

Android对ANR的监控机制
Android应用程序是通过消息来驱动的,Android某种意义上也可以说成是一个以消息驱动的系统,UI、事件、生命周期都和消息处理机制息息相关。Android的ANR监测方案也是一样,大部分就是利用了Android的消息机制。


anr.png

2.主流的ANR监控方案

主流的ANR监控方案:FileObserver,WatchDog,Looper.loop。它们都各有优缺点,无法覆盖所有情况,所以在线上使用的时候可以结合这几种方案一起使用。

2.1 FileObserver实现ANR监控

当ANR发生的时候,我们是可以通过监听该文件目录data/anr/的写入情况来判断是否发生了ANR,看起来这是一个不错的时机。需要注意的是,所有应用发生ANR的时候都会进行回调,因此需要做一些过滤与判断,如包名、进程号等。

优点:

  1. 基于原生接口调用,时机和内容准确
  2. 无性能问题实现简单

缺点:
最大的困难是兼容性问题,这个方案受限于Android系统的SELinux机制,5.0以后基本已经使低权限应用无法监听到trace文件了,但是可以在开发内测阶段通过root手机进行监控。

2.2 ANR-WatchDog实现ANR监控

ANR-WatchDog是参考Android WatchDog机制(com.android.server.WatchDog.java)起个单独线程向主线程发送一个变量+1操作的消息,然后自我休眠sleep 自定义ANR的阈值一般是5s,休眠过后判断变量是否+1完成,如果未完成则告警。

watchdog.png

优点:

  1. 兼容性好,各个机型版本通用
  2. 无需修改APP逻辑代码,非侵入式
  3. 逻辑简单,性能影响不大

缺点:
无法保证能捕捉所有ANR,对阈值的设置直接影响捕获概率.比如如果设置了5s就无法捕获10s的Receiver和20s的service 引起的ANR。

2.3 Looper.loop实现ANR监控

巧妙的利用了Android原生Looper.loop中的一个log打印逻辑。
这个log打印逻辑正是在Message消息分发前后,大部分的性能卡顿问题都是在这里发生的,监控这两个逻辑之间的时间差就可以得到当前主线程的卡顿状态,如果超时则获取trace信息并上报。

实现原理:开启子线程执行,会消耗cpu资源,谨慎开启,开发中一般针对部分用户下发开关:

  1. 设置Looper.setPrinter(自定义printer)实现println方法;
  2. 在消息执行前后,Looper会调用
    Looper.mPriter.pritlin(“>>>>> dispatch msg.target msg.callBack,msg.what”)//子线程开启收集线程堆栈信息
    Looper.mPriter.pritlin(“<<<<<< finish msg.target msg.callBack,msg.what”)//子线程结束收集线程堆栈信息
  3. 首先需要判断msg.target的Looper是否等于主线程的Looper.
  4. 其次计算这两个函数前后时间差是否超过200ms超过的话就上报堆栈调用信息。

优点:

  1. 灵活配置可监控常见APP应用性能也可作为一部分场景的ANR监测,并且可以准确定位ANR和耗时调用栈。

  2. 谷歌已经明确标注This must be in a local variable, in case a UI event sets the logger这个looger对象是可以被更改的,已经有开发者遇到在使用WebView时logger被set为Null导致,进而造成监控失败。

3.如果dispatchMessage消息执行的非常久是无法触发监控的逻辑。

4.无法监控CPU资源紧张造成系统卡顿,无法响应的ANR

2.4 注册信号函数

使用注册信号函数机制监听SINGAL_QUIT信号,可以监听ANR和Crash触发逻辑。可以作为FileObserver在5.0以后因权限问题无法监测data/anr目录的使用。
因为当应用发生crash和ANR的时候,系统会向目标进程发送SIGNAL_QUIT信号,应用虚拟机捕获到信号以后会收集系统信息输出到日志文件中(data/anr/trace.txt)然后kill掉目标进程。trace文件中数据过大,可以根据当前时间节点和进程id进行信息过滤。详情参考:让Native Crash 与ANR无处发泄

3.总结

ANR监控方案各有优劣,开发中一般组合多个共同使用。
Crash,ANR,卡顿最难的是异常信息的收集上传,收集到信息后可以根据日志进行分析进而解决问题。信息(一般是将日志保存在本地,有效期限是七天)上传一般都是通过开关动态下发的,目的是为了节省带宽和服务端的存储压力。千万级的用户数据量会很大。

在灰度期间重点观察指标是否正常,如果正常扩大灰度继续观察,不正常的话就停止灰度。然后定位问题是升级还是采用热修复。

相关文章

  • ANR监控方案总结

    1.前言 ANR比较棘手在于,没有崩溃日志,定位问题比较困难,而且ANR是必须要解决的问题。 Android对AN...

  • Android卡顿监控

    实现思路 卡顿监控主要监控:慢方法的监控、ANR的监控、掉帧的监控。其实现方案主要有三种: Looper的Prin...

  • [ANR监控] 用StrictMode进行线下监控

    ANR的监控策略,可以分为线上和线下。线上的监控方案,需要充分考虑性能问题,所以很多监控策略不能使用。但是线下监控...

  • 今日头条 ANR 优化实践系列 - 告别 SharedPrefe

    简述 前面系列文章中介绍了安卓系统ANR设计原理以及我们在实际工作中对ANR进行监控得到的一些方案,基于这些常规的...

  • 手把手教你高效监控ANR

    ANR监控是一个非常有年代感的话题了,但是市面上的ANR监控工具,或者并非真正意义上的ANR的监控(而是5秒卡顿监...

  • Android ANR监控

    1. 前言 上一篇文章讲到了Java层Crash的监控,其实App除了Crash外,ANR也是一个头疼的问题。 A...

  • ANR问题分析

    本文站在系统角度来简单总结下ANR分析的一般套路。 一、ANR简介 1.1 ANR定义 ANR(Applicati...

  • Android framework学习之Android11.0

    掉帧监控,函数插桩,慢函数检测,ANR监控,启动监控……这些让Android开发者们头皮发麻的内容,如今可都成为了...

  • 前端监控方案探究

    最近有在总结一些前端监控的方案,这篇文章用来做一个汇总,篇幅会以方案描述和方法论为主,也会有部分代码。 性能监控 ...

  • Android应用稳定性优化

    提高代码质量 Crash监控 ANR剖析 提高后台进程存活率未完待续

网友评论

    本文标题:ANR监控方案总结

    本文链接:https://www.haomeiwen.com/subject/bqvtortx.html