网易云信 Crash 异常治理实践 | 智企技术委员会技术专题系列

4,778 阅读12分钟

前言

Crash(造成用户无法使用客户端所承载的服务)作为客户端稳定治理的最主要问题之一。云信作为国内业界领先的 RTC/IM PaaS 服务商,对于客户端 SDK(PaaS 服务商对外服务的主要载体)的 Crash 治理再重视也不为过。关于客户端 Crash 稳定性治理,尽管业界已有多个成熟的监控平台,实现了从埋点、上报、展示到报警一站式服务,如 Bugly 平台、Fabric 平台等,也有 Crash 捕捉的工具 SDK,方便在此基础上按需定制监控平台,如 KSCrash、Breakpad 等。但对于云信这样的 RTC&IM PaaS 服务商来讲,无论是市面上现有 APP Crash 治理平台,还是 Crash 捕捉工具 SDK 都是无法解决针对 PaaS 服务商 Crash 异常治理痛点。

  • 平台类型支持有限

业内平台往往只覆盖主流的两个移动端平台 iOS/Android、对于 Mac OS/PC/Linux/Flutter 不支持。

  • APP 与 SDK 监控数据无法有效隔离

业内对外服务的 Crash 收集平台基本都是设计服务于 APP,后台分析与展示无法同时对 APP 和 SDK 进行区分。

  • 问题治理实现不了闭环处理

以业内著名 Bugly 为例,只提供了对外闭源 SDK,Bugly 后端目前也没有开放第三方接口,崩溃信息都要人工去主动搜索处理,无法与 PaaS 服务商内部 Bug 管理系统进行联动,异常感知也没法自动感知与推送,形成不了 Crash 问题从捕获到研发人员响应处理高效的闭环。

Crash 异常治理建设

为了解决以上 PaaS 服务商稳定性问题治理的痛点,构建一套从异常问题捕捉到研发人员高效问题处理的监控分析系统就显得格外迫在眉睫了,云信研发团队从以下三个维度思考:

  • 如何实现数字体验监控: 采集的指标有哪些,以及这些指标的影响是什么?
  • 异常发现、跟踪及诊断: 异常指标如何转化为具体可处理的方案,如何快速找到问题模块?
  • 面向技术人员的自动化运维: 如何实现问题分析的精准性,如何降低研发分析耗时与成本?

经过大半年多的努力,终于落地了 Crash 稳定性治理平台(以下简称 Marvel)平台,实现了 Crash 问题的高效治理。该平台基于 PaaS 服务商的特点,设计了三级的账号体系,平台覆盖了 Android、iOS、Windows、MAC、Linux、Web 平台、Flutter 框架, 最终实现从问题捕获、分析处理问题、修复、复盘全链路的闭环,下文将针对该平台做较为详细的介绍。

平台架构设计

1.png

Marvel 平台架构设计图

如上图所示, 从数据流角度可知,当 CI 构建服务完成产品各个客户端平台 SDK 包的时候,系统会自动将 SDK 包对应平台的符号表文件上传到 NOS(网易对象存储)文件服务,同时将 SDK 版本号、各个 SO 库的 build_id/uuid、Github 仓库地址等元信息记录到平台数据库中,为后续异常解析服务查找奔溃库所属的符号表文件做准备。当 C 端发生 Crash 问题的时候,系统首先会将 Crash 信息(栈信息、用户操作轨迹、uuid/build_id 等信息)上传到 Marvel 后台服务,系统经过数据清洗以及异常解析之后,精准地分析出该 Crash 属于哪个模块,平台支持根据模块归属人查询表或者根据 git commit 记录查找出最后代码变更人, 最终自动生成 Jira 工单,然后通过公司内部协作工具(POPO)同步异常待处理消息给对应的研发同学。从而最终实现了线上异常处理的自动化闭环操作。

平台全景视图

2.png Marvel 系统全景视图

云信当前 Marvel 平台除了重点落地实现了 Crash 稳定性问题治理之外,同样也实现了部分平台其它稳定性问题的治理,如卡顿、内存泄漏、内存溢出、ANR、Watchdog 等客户端的稳定性问题,稳定性问题发生的上下文信息(用户的行为轨迹、应用的上下文等信息数据),通过 ES 搜索引擎和 HBASE 数据库实现海量数据的存储以及快速数据聚合查询,最终能够快速实现场景还原,实现问题的重现,最终实现快速分析定位问题。

账号体系设计

传统的异常捕获系统是基于 APP 维度来统计 Crash 等异常信息的,而作为 PaaS 服务商,希望看到的是从 PaaS 服务产品及对应的 SDK 维度来统计 Crash 信息,因此云信设计了三级的账号体系,以支持每个层级来做聚合统计监控。

3.png 账号体系设计图

三级账号体系说明如下:

  • 公司级别。 如易盾、云信等 PaaS 服务厂商。
  • 公司产品SKU。 如云信有 IM SDK、RTC SDK、播放器 SDK。
  • SKU 下的子产品。 如 RTC SDK 下有美颜、背景替换、水印等插件化的子产品。

治理涵盖研发全周期

4.png 稳定性问题治理周期

稳定性问题治理需要贯穿整个软件研发的完整生命周期,包括需求研发、测试、集成、灰度、上线等,上述每个阶段,研发同学都应该格外重视稳定性问题的发现和治理。于是针对各个阶段的数据采集也就格外的重要,当前云信的稳定性问题治理平台已经完成了线下场景的全覆盖,以及线上场景的部分覆盖。当前上传到平台的数据主要分为 Monitor、Logging、Tracing 三类。Trace 数据主要指的是代码调用栈数据;Log 主要是用户行为轨迹数据、客户端系统日志等;Monitor 数据主要是与人们异常模型相匹配的异常数据。

端侧功能集

5.png

端侧 Marvel SDK 功能模块

端侧 SDK 层面功能以小的颗粒度接入。在设计开发上实现采集功能的模块化,各个应用可以根据自身需要选择性引用功能模块,从而保证稳定性监控 SDK 对于应用的包体积及性能达到最小影响。除了提供原子的监控采集能力外,为了实现监控 SDK 的容错与容灾能力,Marvel 平台除了会对线上应用实时采集功能开关控制之外,监控 SDK 当遇到本身运行异常的时候也会自动进行功能关闭,对于问题能够做到自动隔离。

堆栈解析服务

在每个异常上报中,除了基础元信息外,还包括异常类型、异常消息、异常堆栈等运行时内容,特别是堆栈信息,能够有效地协助研发去识别异常点。那么我们就可以依据堆栈和异常类型来做聚合。

简单来说,可以按照堆栈信息做 Hash 比对来去重,虽然该方案能够大幅减少重复异常,但还是会存在大量同类问题归结为不同类别的情况,例如在递归情况下的异常,递归深度不同就会导致 hash 结果不一致。考虑 ROI 比当前我们只截取非系统的用户函数堆栈,后期考虑引入些更高级的算法, 对相似的堆栈能够更加精准的归因(如对堆栈距离、TF-IDF 等手段对堆栈的内容进行解析,然后利用相应的公式来计算两个堆栈之间的相似性)。

从可观察性的指标来看堆栈信息对应就是 Tracing 数据,堆栈还原服务是决定后续是否能对问题进行精准分析归因的关键。通过还原后堆栈信息 Marvel 可以快速定位到代码行。然而线上运行时的程序为了安全和安装包体大小等因素,会对代码进行混淆或者压缩,所以获取到的堆栈文本是混淆压缩后的堆栈信息。为了使开发人员直观快速地理解堆栈含义,这就需要使用相关的符号文件来对混淆或者压缩的代码信息做还原处理。

表1.png 客户端平台堆栈还原支持情况

早期 Marvel 符号化解析主要依赖原生平台工具,但存在以下问题:

  • 低性能

因为各个端提供的是命令行工具,所以需要在服务内部通过命令行调用,这种启动子进程的方式会带来大量的进程创建和销毁的性能损耗。此外,因为需要启动命令行子进程处理,处理跨进程通信也会带来较大的性能开销;通过命令行每次调用都要重复读取解析符号文件,带来了额外的性能开销。

  • 难维护

因为命令行是通过子进程处理,无法管理命令行子进程的状态,对命令行的异常的定位解决带来了复杂性;不同端的工具会依赖不同语言和运行环境,例如 iOS 的 atos 需要运行在 MacOS 环境下,这个对服务的统一部署非常不友好。

为了解决以上问题,当前 Marvel 采用 Rust 实现了各个端侧的符号解析,保证各个符号信息只做一次解析,并转为 KV 结构形式缓存处理。统一语言后也能降低程序运维复杂性,并服务 docker 容器化的需求。

当前堆栈还原相关的主要有两个服务:

  • 符号表管理服务

负责符号表的上传、下载、解析、缓存等流程的管理。符号表上传之后,该模块会实时解析文件,并将其解析为 KV 的形式写入 Redis 缓存之中。同时,还会负责符号表文件存储和缓存的管理。

  • 堆栈还原服务

负责堆栈还原,以 gRPC 的形式提供还原服务。当接收到还原请求时,会在 Redis 中查找相关的符号信息,并将这些信息拼接为完整的堆栈,返回给请求发送端。

异常问题自动化分发

上一章节介绍了 Marvel 平台系统的整体架构设计、账号体系设计、端侧功能集、堆栈解析服务等重点模块实现,本章节将重点讲解平台对于 Crash 异常问题的高效分发处理。

一个高效稳定性治理平台,自动精准分发异常的能力是必不可少的, 帮助 PaaS 服务方快速收到报警、快速响应用户遇到的问题。关于系统是如何根据堆栈信息来追踪与查询 Crash 处理研发人员了,上节第一 小节已详细说明,这里就不再重复了。

问题分发云信当前主要采取以下两个策略:

  • 包含业务堆栈的异常, 通过构建集成平台的组件维护人员信息,直接指派到开发负责人。
  • 对于没有业务栈帧的异常, 根据平台上项目创建人进行指派。

下文以 iOS 稳定性治理为例展示平台系统实现。

1. 聚类展示

6.png Crash 异常问题聚类 UI 展示

2. 异常链接推送

7.png SDK 系统异常链接推送通知

3. 工单创建通知

8.png POPO- JIRA 建单链接推送

4. 平台异常与 Jira 关联

9.png 平台 Crash 异常与 Jira 关联

5. 异常项与 CI 产物符号表关联

10.png Crash 异常与 SDK 版本符号表关联

6. 异常堆栈还原展示

11.png Crash 异常堆栈还原图

总结与展望

以上就是云信研发团队对于客户端 Crash 稳定性问题治理与总结,文章针对 Marvel 平台的架构设计、账号体系设计、治理周期、端侧功能、堆栈解析服务等进行了详细阐述。该平台的落地使得云信的研发效能得到了大大提升。在 Marvel 平台上线前, Crash 等稳定性问题异常处理如下图所示,全流程人工作业,排查问题需要前后反复沟通,并且数据源完全依赖终端用户配合导出崩溃数据,响应链路长并且往往存在缺少数据源而没法定位的问题,产研侧也无法主动感知线下/线上的稳定性问题。

旧流程:

12.png

13.png

新流程:

14.png

后续云信研发团队将继续从以下几方面进一步建设与完善 Marvel 平台。

完善端侧疑难杂症的问题治理

  • 覆盖与完善更多端侧的稳定性问题治理;
  • 如 Android oom 治理 , 完善内存治理手段与分析 ,下一步完善问题判定规则。

一站式服务

端侧的问题并非孤立存在,它可能会受到后端的服务质量影响,双端的数据联通与关联能够为业务构建起完整的应用质量地图。后续 Marvel 将与更多内部平台联动如后台监控、后台日志团队在数据服务上做联动,为应用服务提供一站式监控、定位、容灾服务能力。

智能归因分析

本着数据驱动的理念,以及高效挖掘并利用已有数据的思路。Marvel 后续将通过结合研发期间的数据,通过发布信息、代码变更信息、测试案例等,构建研发流程画像,同时结合线上观测数据与问题详情构建的线上质量画像,实现快速聚合分析归因,做到研发内问题提前预警,以及线上问题的在代码和责任人层面的根因分析,降低研发排查问题的时间消耗以及人员沟通成本,助力效能提升。