作者简介
辛贵,携程无线研发总监。主要负责App基础框架研发相关工作,关注App开发框架、性能、质量、效率和新技术。
APM全称为Application Performance Management,即应用性能管理,对于一款成熟的App,各项性能指标的监控是必不可少的。公司内部早前有个1.0版本的APM系统,主要存以下问题:筛选功能薄弱、缺少日报和告警功能、功能混杂、且只支持单一App。鉴于以上问题,我们发起了APM2.0版本的重构,在开始之前,我们重新梳理了APM的定位,以及该做哪些功能。
最终,确定APM定位为数据报表+性能日报+监控告警+排障入口,具体如下:
功能模块上,主要包括网络性能、页面性能、崩溃卡顿和专项性能四部分,下面章节会继续介绍。
网络请求性能是App的核心性能指标之一,APM平台以端到端的数据为基准,进行性能统计,这样最能反映用户的真实感受。
如下图所示,App中的动态网络请求,都是通过自研的网络通讯框架发送到后端Gateway,Gateway再将服务转发给真实业务服务器。
几点简单说明:
端到端的网络请求异常数据,大多数是发生在链路的建立和数据传输上。由于我们是自己管理的TCP链路,因此对请求链路的可控性更加强,我们梳理了整个请求链路,对整个链路上存在异常的点,都定义了对应的code。参考下图:
主要以下code:
Code | 定义 | 说明 |
---|---|---|
-202 | 请求序列化失败 | 极小概率出现 |
-203 | 无可用链路 | 比例较高,无法连接到服务器,即为常见的网络不稳定 |
-204 | 发送请求失败 | socket send失败,极小概率 |
-205 | 读取响应出错 | 链路异常,读不到指定长度的响应头 |
-206 | 响应反序列化失败 | 极小概率出现 |
-212 | 链路异常断开 | 包括客户端网络异常和后端主动断开 |
-213 | 读取不到响应 | 比例较高,即为常见的超时 |
以上错误code,主要是聚焦在自建TCP链路层面的异常,对于标准的HTTP Error,比如HTTP的4xx,5xx也会记录,一般出现这些错误的时候链路本身并不会出现错误(限TCP通道)。
主要监控端到端请求的成功率和耗时两个数据维度。
下面几张截图是网络性能模块设计的报表:
上图是分版本,业务部门的性能概览数据,蓝色的字体,都是可以点击进行过滤筛选的。
上图是按照具体服务号,列出该服务的成功率、总耗时、服务端处理耗时、样本量、还有错误code分布。
每个表格后面都有一个采样功能,点击该按钮,即可进行采样,选择一批错误或者是耗时较长的设备ID,点击设备ID,可以跳转到内部排障系统,查看更多详细信息,进行整个问题的排查。
上图是内部排障系统中的一个小工具,可以根据一条链路ID来把该链路上的所有请求有序排列展示, 这对于日常排障非常有帮助,可以极大的提高网络问题的排障效率。
2.1.5 性能优化实践
以下是我们在进行端到端网络性能优化过程中的一些实践经验,简单介绍几个效果较好的优化方案。
一般在收到统计页面性能需求的时候,开发人员最常规的做法是在页面初始化的时候,设置一个时间点,然后在渲染所需的一个(组)服务发送完,页面渲染之后,设置一个结束点,两者相减,就是页面的可交互时间。
这种做法的统计是准确的,但是需要每个页面都去做这个逻辑,对于一些复杂页面,对于不同的业务逻辑,需要做多套这样的性能埋点处理。且后续随着业务的迭代,性能统计的逻辑还需要确保没有问题。
对于业务开发来说,这无疑是大大增加了工作量,我们希望能有一个框架层的方案,去统计页面渲染完成或者是可交互时间点(Time To Interactive)的性能,以便让业务开发人员从性能埋点中解放出来。
首先考虑到了页面截屏+像素点检测的方案去检测页面渲染完成时间点,思路如下:
按照这个思路实现并灰度上线了这套检测方案,基本准确的检测出页面渲染时间,但是也存在一些问题:
由于以上问题,这个数据上线之后,没能推广给业务开发同事去使用。继续优化,我们发现:
在这两个观点支撑下,我们对检测方案做起了重构,将页面截屏+像素点的随机选取,替换成页面组件扫描+文案检查。大致流程如下:
以下视频是我们检测的demo,三个页面分别不同的技术栈,Native/CRN/H5, 可以看到,基本都是在内容加载完成的时候,toast弹出来提示页面检测完成。
该方案虽无法确认页面内元素是否完全渲染完成,但可以确定页面已经有内容,用户可以进行交互。所以我们将文案检测成功的时间点当做页面可交互的时间点,以此来作为页面的TTI(Time To Interactive, 后文使用TTI缩写)性能。
上线之后,我们看到APM报表的数据,能比较真实的反映页面性能。
下图是APM平台上的页面TTI性能报表,支持多维度的筛选过滤,也支持采样功能。
对于每一个(组)页面,还能显示页面的TTI耗时分布,这对业务BU进行性能优化非常有帮助,简单相加就可以计算出页面TTI性能的95线,90线耗时。
在TTI性能表格的第一列,有一个页面类型,我们给每一个页面一个类型,每种类型设置一个TTI性能基准,TTI性能如果在基准之内的,显示绿色,超过基准20%的,显示红色,表示需要优化。以下是我们定义的基准,业务部门研发同事的页面性能优化以此为标准。
2.2.3 页面TTI性能优化
在配合业务团队研发同事进行页面TTI性能优化的过程中,积累了一些经验和优化方案。
崩溃卡顿系统,和大家常用的崩溃采集系统基本一致,这里不过多介绍。经常有用户投诉说遇到了闪退,但工程师在后台Crash收集系统里面却搜索不到对应的Crash日志。
技术的角度来说,是可以理解的,因为没有哪个Crash收集 SDK能够捕获所有的Crash,即便是操作系统也有一些不能捕获的,在iOS上也经常遇到App Crash之后在系统的设置里面,找不到对应的Log。
为了辅助统计用户遇到Crash的情况,我们在App启动的时候,去检测用户上次使用过程中是否有遇到Crash,如果有则上报上来,再开发成如下的用户行为Crash报表:
判断用户是否有Crash策略大致如下:
以上方案不能完全准确的统计用户是否遇到Crash,有些Case无法捕获,但多个版本纵向对比还是有意义的, 且随机采样几个用户行为进行分析,发现确实有Crash出现;
在开发过程中,经常会有各种Exception需要处理。大多时候开发人员直接将exception print出来,不做其他处理,也有部分Exception的处理需要单独埋点,后续再开发报表,这样做是比较严谨的,但是工作量偏高。
为了解决这些问题,我们提供了logException的API,以及如下的报表,方便开发人员直接上报Exception。上报之后,APM的报表会按照title(图中的Category)和subTitle(图中的Message)两级的方式组织报表,并提供采样功能,方便问题的排查分析。
本文主要介绍了我们为了监控App的网络性能、页面性能和稳定性这三个核心性能指标而开发的APM系统,实践下来,发现APM系统在以下几个方面对比较有价值:
本文介绍的只是APM系统的核心部分,实际上还有大量定制功能无法一一展开,比如告警和性能日报、自定义报表、各类专项性能等。希望我们在网络性能、页面性能和稳定性方面的实践经验对大家有所启发。
注:“携程技术”微信公众号后台回复“apm”,可下载讲师分享PPT。