【Android -- 性能优化】稳定性优化

不断学习,做更好的自己

视频号 CSDN 简书
欢迎打开微信,关注我的视频号:程序员朵朵 点我 点我

一、前言

  • 稳定性很重要,Crash是P0优先级
  • 稳定性可优化的面很广

1. 稳定性纬度

  • Crash纬度
  • 性能纬度:启动速度、内存、绘制等等优化方向,相对于Crash来说是次要的
  • 业务高可用纬度

2. 稳定性优化概述

  • 重在预防、监控必不可少
  • 思考更深一层、重视隐含信息:如解决Crash问题时思考是否会引发同一类问题
  • 长效保持需要科学流程

3. Crash相关指标

  • UV、PV
    PV(Page View):访问量
    UV(Unique Visitor):独立访客,0 - 24小时内的同一终端只计算一次

  • UV、PV、启动Crash率
    UV Crash率:针对用户使用量的统计,统计一段时间内所有用户发生崩溃的占比
    Crash UV / DAU:评估Crash率的影响范围,结合PV
    注意:沿用同一指标
    PV Crash率:评估相关Crash影响的严重程度
    启动Crash率:影响最严重的Crash,对用户伤害最大,无法通过热修复拯救,需结合客户端容灾
    增量、存量Crash率:增量Crash是新版本重点,存量Crash是需要持续啃的硬骨头,优先解决增量、持续跟进存量

4. Crash率评价

  • 必须在千分之二以下
  • 万分位为优秀

5. Crash关键问题
尽可能还原Crash现场:

  • 堆栈、设备、OS版本、进程、线程名、Logcat
    前后台、使用时长、App版本、小版本、渠道
    CPU架构、内存信息、线程数、资源包信息、用户行为日志
  • Crash现场信息、Crash Top机型、OS版本、分布版本、区域
    Crash起始版本、上报趋势、是否新增、持续、量级
    根据以上信息决定Crash是否需要立马解决以及在哪个版本进行解决
  • 参考Bugly平台的APM后台聚合展示

6. APM Crash部分整体架构
采集层

  • 错误堆栈
  • 设备信息
  • 行为日志
  • 其它信息

处理层

  • 数据清洗
  • 数据聚合
  • 纬度分类
  • 趋势对比

展示层

  • 数据还原
  • 纬度信息
  • 起始版本
  • 其它信息

报警层

  • 环比:期与上一期进行对比
  • 同比:如本月10号与上月10号
  • 邮件
  • IM
  • 电话

责任归属

  • 设立专项小组轮值
  • 自动匹配责任人
  • 处理流程全纪录

二、Crash优化

1. 单个Crash处理方案

  • 根据堆栈及现场信息找答案
    解决90%问题
    解决完后需考虑产生Crash深层次的原因

  • 找共性:机型、OS、实验开关、资源包,考虑影响范围

  • 线下复现、远程调试

2. Crash率治理方案

  • 解决线上常规Crash

  • 系统级Crash尝试Hook绕过

  • 疑难Crash重点突破或更换方案

3. Java Crash
出现未捕获异常,导致出现异常退出。

Thread.setDefaultUncaughtExceptionHandler()

我们通过设置自定义的 UncaughtExceptionHandler,就可以在崩溃发生的时候获取到现场信息。注意,这个钩子是针对单个进程而言的,在多进程的APP中,监控哪个进程,就需要在哪个进程中设置一遍ExceptionHandler。

获取主线程的堆栈信息:

Looper.getMainLooper().getThread().getStackTrace();

获取当前线程的堆栈信息:

Thread.currentThread().getStackTrace();

获取全部线程的堆栈信息:

Thread.getAllStackTraces();

第三方 Crash 监控工具如 Fabric腾讯Bugly,都是以字符串拼接的方式将数组 StackTraceElement[] 转换成字符串形式,进行保存、上报或者展示。

4. Native Crash
特点:

  • 访问非法地址
  • 地址对齐出错
  • 发送程序主动 abort

上述都会产生相应的signal信号,导致程序异常退出。

  • 合格的异常捕获组件
    一个合格的异常捕获组件需要包含以下功能:
    • 支持在crash时进行更多扩张操作
    • 打印logcat和日志
    • 上报crash次数
    • 对不同crash做不同恢复措施
    • 可以针对业务不断改进的适应
  • 现有方案
    • Google Breakpad
      优点:权威、跨平台
      缺点:代码体量较大

    • Logcat
      优点:利用安卓系统实现
      缺点:需要在crash时启动新进程过滤logcat日志,不可靠

    • coffeecatch
      优点:实现简洁、改动容易
      缺点:有兼容性问题

三、ANR 优化

1. ANR 发生原因
没有在规定的时间内完成要完成的事情。

2. 发生场景

  • Activity onCreate 方法或 Input 事件超过 5s 没有完成
  • BroadcastReceiver前台 10s,后台 60s
  • ContentProvider 在publish过超时 10s;
  • Service前台 20s,后台 200s

3. 发生原因

  • 主线程有耗时操作
  • 复杂布局
  • IO操作
  • 被子线程同步锁block
  • Binder对端block
  • Binder被占满导致主线程无法和SystemServer通信
  • 得不到系统资源(CPU/RAM/IO

四、移动端业务高可用方案建设

业务高可用重要性

  • 高可用
  • 性能
  • 业务
  • 侧重于用户功能完整可用
  • 真实影响收入

业务高可用方案建设

  • 数据采集

  • 梳理项目主流程、核心路径、关键节点

  • Aop自动采集、统一上报

  • 报警策略:阈值报警、趋势报警、特定指标报警、直接上报(或底阈值)

  • 异常监控

  • 单点追查:需要针对性分析的特定问题,全量日志回捞,专项分析

  • 兜底策略

  • 配置中心、功能开关

  • 跳转分发中心(组件化路由)

移动端容灾方案
灾包括:

  • 性能异常
  • 业务异常

传统流程:
用户反馈、重新打包、渠道更新、不可接受。

容灾方案建设

  • 功能开关
    配置中心,服务端下发配置控制
    针对场景:

    • 功能新增
    • 代码改动
  • 统跳中心

    • 界面切换通过路由,路由决定是否重定向
    • Native Bug不能热修复则跳转到临时H5页面
  • 动态化修复

    • 热修复能力,可监控、灰度、回滚、清除
  • 推拉结合、多场景调用保证到达率

  • Weex、RN增量更新

  • 安全模式
    微信读书、蘑菇街、淘宝、天猫等“重运营”的APP都使用了安全模式保障客户端启动流程,启动失败后给用户自救机会。先介绍一下它的核心特点:

    • 根据Crash信息自动恢复,多次启动失败重置应用为安装初始状态
    • 严重Bug可阻塞性热修复
  • 安全模式设计
    配置后台:统一的配置后台,具备灰度发布机制
    1、客户端能力:

    • APP连续Crash的情况下具备分级、无感自修复能力
    • 具备同步热修复能力
    • 具备指定触发某项特定功能的能力
    • 具体功能注册能力,方便后期扩展安全模式

    2、数据统计及告警

    • 统一的数据平台
    • 监控告警功能,及时发现问题
    • 查看热修复成功率等数据

    3、快速测试

    • 优化预发布环境下测试
    • 优化回归验证安全模式难点等

天猫安全模式原理

1、如何判断异常退出?

APP启动时记录一个flag值,满足以下条件时,将flag值清空

  • APP正常启动10
  • 用户正常退出应用
  • 用户主动从前台切换到后台

如果在启动阶段发生异常,则flag值不会清空,通过flag值就可以判断客户端是否异常退出,每次异常退出,flag值都+1。

2、安全模式的分级执行策略

分为两级安全模式,连续Crash 2次为一级安全模式,连续Crash 2次及以上为二级安全模式。

业务线可以在一级安全模式中注册行为,比如清空缓存数据,再进入该模式时,会使用注册行为尝试修复客户端
如果一级安全模式无法修复APP,则进入二级安全模式将APP恢复到初次安装状态,并将Document、Library、Cache三个根目录清空。

3、热修复执行策略

只要发现配置中需要热修复,APP就会同步阻塞进行热修复,保证修复的及时性

4、灰度方案

灰度时,配置中会包含灰度、正式两份配置及其灰度概率
APP根据特定算法算出自己是否满足灰度条件,则使用灰度配置

易用性考量

1、接入成本

完善文档、接口简洁

2、统一配置后台

可按照APP、版本配置

3、定制性

支持定制功能,让接入方来决定具体行为

4、灰度机制

5、数据分析

采用统一数据平台,为安全模式改进提供依据

6、快速测试

创建更多的针对性测试案例,如模拟连续Crash

异常熔断

多次请求失败则可让网络库主动拒绝请求

容灾方案集合路径

功能开关 -> 统跳中心 -> 动态修复 -> 安全模式

五、稳定性长效治理

开发阶段

  • 统一编码规范、增强编码功底、技术评审、CodeReview机制
  • 架构优化
  • 能力收敛
  • 统一容错:如在网络库utils中统一对返回信息进行预校验,如不合法就直接不走接下来的流程。

测试阶段

  • 功能测试、自动化测试、回归测试、覆盖安装
  • 特殊场景、机型等边界测试:如服务端返回异常数据、服务端宕机
  • 云测平台:提供更全面的机型进行测试

合码阶段

  • 编译检测、静态扫描
  • 预编译流程、主流程自动回归

发布阶段

  • 多轮灰度
  • 分场景、纬度全面覆盖

运维阶段

  • 灵敏监控
  • 回滚、降级策略
  • 热修复、本地容灾方案

六、稳定性优化问题

1、你们做了哪些稳定性方面的优化?

  • Crash专项优化
  • 性能稳定性优化
  • 业务稳定性优化

根据以上三方面的优化我们搭建了移动端的高可用平台。

2、性能稳定性是怎么做的?

  • 全面的性能优化:启动速度、内存优化、绘制优化
  • 线下发现问题、优化为主
  • 线上监控为主
  • Crash专项优化

3、业务稳定性如何保障?

  • 数据采集 + 报警
  • 需要对项目的主流程与核心路径进行埋点监控,
  • 同时还需知道每一步发生了多少异常,这样,我们就知道了所有业务流程的转换率以及相应界面的转换率
  • 结合大盘,如果转换率低于某个值,进行报警
  • 异常监控 + 单点追查
  • 兜底策略

4、如果发送了异常情况,怎么快速止损?

  • 功能开关
  • 统跳中心
  • 动态修复:热修复、资源包更新
  • 自主修复:安全模式

七、总结

Android 稳定性优化是一个需要长期投入,持续运营和维护的一个过程,只有深入了解这些底层知识,我们才能比别人设计出更好的稳定性优化方案。

你可能感兴趣的:(Android,--,性能优化,性能优化,稳定性优化)