作者简介

辛贵,携程无线研发总监。主要负责App基础框架研发相关工作,关注App开发框架、性能、质量、效率和新技术。

1、背景介绍

APM全称为Application Performance Management,即应用性能管理,对于一款成熟的App,各项性能指标的监控是必不可少的。公司内部早前有个1.0版本的APM系统,主要存以下问题:筛选功能薄弱、缺少日报和告警功能、功能混杂、且只支持单一App。鉴于以上问题,我们发起了APM2.0版本的重构,在开始之前,我们重新梳理了APM的定位,以及该做哪些功能。

最终,确定APM定位为数据报表+性能日报+监控告警+排障入口,具体如下:

  • 数据报表

    • 端到端精准数据报表

    • 多维度筛选功能支持

    • 多App报表支持

    • 实时报表

  • 性能日报

    • 核心性能指标提供邮件日报功能

    • 支持订阅功能

  • 监控告警

    • 适合告警的核心指标,进行告警

    • Crash率,JSError等告警

  • 排障入口

    • 支持多维度的异常数据、错误数据采样

    • 采样数据和内部系统打通

功能模块上,主要包括网络性能、页面性能、崩溃卡顿和专项性能四部分,下面章节会继续介绍。

2、主要功能

2.1 网络性能

网络请求性能是App的核心性能指标之一,APM平台以端到端的数据为基准,进行性能统计,这样最能反映用户的真实感受。

2.1.1 网络架构模型

如下图所示,App中的动态网络请求,都是通过自研的网络通讯框架发送到后端Gateway,Gateway再将服务转发给真实业务服务器。

几点简单说明:

  • 网络通讯框架和Gateway之间会通过TCP长连接进行通讯;

  • 网络通讯框架和Gateway之间数据协议为自定义契约格式协议;

  • 网络通讯框架可以将HTTP协议转换成自定义协议进行代理转发;

  • Gateway本身业务逻辑较少,只负责链路管理和请求路由转发,为了让用户有好的体验,我们做了全球部署;

  • 所有动态请求都通过网络框架发送,在这个点做好采样埋点,即可为APM报表提供精准数据源;

2.1.2 错误监控维度

端到端的网络请求异常数据,大多数是发生在链路的建立和数据传输上。由于我们是自己管理的TCP链路,因此对请求链路的可控性更加强,我们梳理了整个请求链路,对整个链路上存在异常的点,都定义了对应的code。参考下图:

主要以下code:

Code 定义 说明
-202 请求序列化失败 极小概率出现
-203 无可用链路 比例较高,无法连接到服务器,即为常见的网络不稳定
-204 发送请求失败 socket send失败,极小概率
-205 读取响应出错 链路异常,读不到指定长度的响应头
-206 响应反序列化失败 极小概率出现
-212 链路异常断开 包括客户端网络异常和后端主动断开
-213 读取不到响应 比例较高,即为常见的超时

以上错误code,主要是聚焦在自建TCP链路层面的异常,对于标准的HTTP Error,比如HTTP的4xx,5xx也会记录,一般出现这些错误的时候链路本身并不会出现错误(限TCP通道)。

2.1.3 监控的维度与目标

主要监控端到端请求的成功率和耗时两个数据维度。

  • 请求成功率

    • 计算方式:请求成功次数/(请求成功次数+请求失败次数)

    • 目标 - 用户交互场景:目标99%+

    • 目标 - 整体平均:目标98%+,包含启动、后台场景的请求,这部分请求成功率相对较低

  • 请求耗时

    • 计算方式:客户端发起请求为起始点,收到响应并序列化完成为结束点

    • 目标 - 用户交互场景:后端处理耗时+300ms(RTT时间)

2.1.4 APM报表

下面几张截图是网络性能模块设计的报表:

上图是分版本,业务部门的性能概览数据,蓝色的字体,都是可以点击进行过滤筛选的。

上图是按照具体服务号,列出该服务的成功率、总耗时、服务端处理耗时、样本量、还有错误code分布。

每个表格后面都有一个采样功能,点击该按钮,即可进行采样,选择一批错误或者是耗时较长的设备ID,点击设备ID,可以跳转到内部排障系统,查看更多详细信息,进行整个问题的排查。

上图是内部排障系统中的一个小工具,可以根据一条链路ID来把该链路上的所有请求有序排列展示, 这对于日常排障非常有帮助,可以极大的提高网络问题的排障效率。

2.1.5 性能优化实践

以下是我们在进行端到端网络性能优化过程中的一些实践经验,简单介绍几个效果较好的优化方案。

  • 自定义通讯协议 使用自定义通讯协议,自管理链路,可以对请求中的每一个环节都做到完整的控制,对于故障排查和后续的性能优化会更加有价值。

  • 合理选择ServerIP 实际上包含两个场景的serverIP选择,一个是App刚启动时候默认使用的ServerIP,另一种是Server端下发适合的ServerIP之后的使用策略;几点经验, 国内场景,同一运营商效果较好,海外场景,服务器在海外部署,比通过加速通道回到国内源站效果要好,启动场景,根据timezone选择ServerIP比较合适;

  • 合理设置超时时间 超时时间设置过小,比如3s,成功率会比设置成15s的明显要低,所以可以根据服务的时效性,合理设置超时时间;

  • 支持重试 符合幂等性的服务,设置可以重试,可以大幅度提升成功率;


2.2 页面性能

2.2.1 页面性能统计方案

页面性能是关系到用户替换最重要的性能指标,如何去度量一个页面的性能,是没有一个通用的标准的。

一般在收到统计页面性能需求的时候,开发人员最常规的做法是在页面初始化的时候,设置一个时间点,然后在渲染所需的一个(组)服务发送完,页面渲染之后,设置一个结束点,两者相减,就是页面的可交互时间。

这种做法的统计是准确的,但是需要每个页面都去做这个逻辑,对于一些复杂页面,对于不同的业务逻辑,需要做多套这样的性能埋点处理。且后续随着业务的迭代,性能统计的逻辑还需要确保没有问题。

对于业务开发来说,这无疑是大大增加了工作量,我们希望能有一个框架层的方案,去统计页面渲染完成或者是可交互时间点(Time To Interactive)的性能,以便让业务开发人员从性能埋点中解放出来。

首先考虑到了页面截屏+像素点检测的方案去检测页面渲染完成时间点,思路如下:

  • 页面截屏,按照一定比例,去掉头部+底部部分

  • 将中间部分分隔成6块

  • 每个小块随机取点,检测像素点的相似度

按照这个思路实现并灰度上线了这套检测方案,基本准确的检测出页面渲染时间,但是也存在一些问题:

  • 性能损耗严重,每次截屏时间100ms

  • 对于一些骨架屏类的页面,会被当做页面渲染完成

  • 因为是随机取像素点,对于简单页面,页面检测的次数有一定的随机性

由于以上问题,这个数据上线之后,没能推广给业务开发同事去使用。继续优化,我们发现:

  • 页面渲染完成的时候,一般都有文本

  • 文本扫描的性能损耗比页面截屏低

在这两个观点支撑下,我们对检测方案做起了重构,将页面截屏+像素点的随机选取,替换成页面组件扫描+文案检查。大致流程如下:

  • 页面初始化开始,遍历页面所有元素,检测text

  • 如果text所在坐标在页面头部(20%)/尾部(25%)区域,忽略 Text >= 2组, 认为检测成功

  • 一轮检测之后,未检测成功,等待50ms进行下一轮检测

  • 总共检测10s,否则超时

以下视频是我们检测的demo,三个页面分别不同的技术栈,Native/CRN/H5, 可以看到,基本都是在内容加载完成的时候,toast弹出来提示页面检测完成。

该方案虽无法确认页面内元素是否完全渲染完成,但可以确定页面已经有内容,用户可以进行交互。所以我们将文案检测成功的时间点当做页面可交互的时间点,以此来作为页面的TTI(Time To Interactive, 后文使用TTI缩写)性能。

2.2.2 页面性能报表

上线之后,我们看到APM报表的数据,能比较真实的反映页面性能。

下图是APM平台上的页面TTI性能报表,支持多维度的筛选过滤,也支持采样功能。

对于每一个(组)页面,还能显示页面的TTI耗时分布,这对业务BU进行性能优化非常有帮助,简单相加就可以计算出页面TTI性能的95线,90线耗时。

在TTI性能表格的第一列,有一个页面类型,我们给每一个页面一个类型,每种类型设置一个TTI性能基准,TTI性能如果在基准之内的,显示绿色,超过基准20%的,显示红色,表示需要优化。以下是我们定义的基准,业务部门研发同事的页面性能优化以此为标准。

2.2.3 页面TTI性能优化

在配合业务团队研发同事进行页面TTI性能优化的过程中,积累了一些经验和优化方案。

  • 主线程耗时任务异步化

    • 将一些耗时,且在主线程操作的任务,调度到后台线程异步执行,可提升页面加载性能

  • 网络请求prefetch可大幅度降低页面TTI时间

    • 网络请求预取,即在页面跳转之前,将下一个页面需要的数据,预先获取回来,进入页面时候,只需要使用已经获取到的缓存数据

    • 可以大幅度提升页面性能,机票,酒店列表页面采用之后,页面TTI性能够有约40%左右的提升;

  • 预执行下一页面必须执行的任务

    • 对下一个页面必须执行的任务,在当前页面提前执行掉

    • 在下一个页面会下载离线包,优化为在当前页面下载下一页面可能使用的离线包;

  • CRN框架层的一些优化

    • 如果有使用ReactNative框架的话,强烈建议升级到0.61及其以上版本,并在Android平台开启hermes引擎;

    • RN提供的接口,大多是异步的,但异步接口在首屏加载,通讯频繁的场景,耗时不可控,可以换成同步API;

  • PreRender

    • 简单来说就是延迟页面跳转,利用延迟的时间进行页面的加载;

    • 只要延迟时间控制的好,对用户感知来说,就是页面在平滑的切换;

2.3 崩溃卡顿

崩溃卡顿系统,和大家常用的崩溃采集系统基本一致,这里不过多介绍。经常有用户投诉说遇到了闪退,但工程师在后台Crash收集系统里面却搜索不到对应的Crash日志。

技术的角度来说,是可以理解的,因为没有哪个Crash收集 SDK能够捕获所有的Crash,即便是操作系统也有一些不能捕获的,在iOS上也经常遇到App Crash之后在系统的设置里面,找不到对应的Log。

2.3.1 用户行为Crash

为了辅助统计用户遇到Crash的情况,我们在App启动的时候,去检测用户上次使用过程中是否有遇到Crash,如果有则上报上来,再开发成如下的用户行为Crash报表:

判断用户是否有Crash策略大致如下:

  • 启动App或者页面切换时候,持久化页面信息;

  • App被切换到后台时候,清空掉持久化的页面信息;

  • 启动App时候,检查上次的页面信息,如果上次页面启动时间和当前时间相差较短,则认为出现了Crash;

以上方案不能完全准确的统计用户是否遇到Crash,有些Case无法捕获,但多个版本纵向对比还是有意义的, 且随机采样几个用户行为进行分析,发现确实有Crash出现;

2.3.2 自定义异常上报

在开发过程中,经常会有各种Exception需要处理。大多时候开发人员直接将exception print出来,不做其他处理,也有部分Exception的处理需要单独埋点,后续再开发报表,这样做是比较严谨的,但是工作量偏高。

为了解决这些问题,我们提供了logException的API,以及如下的报表,方便开发人员直接上报Exception。上报之后,APM的报表会按照title(图中的Category)和subTitle(图中的Message)两级的方式组织报表,并提供采样功能,方便问题的排查分析。

3. 总结

本文主要介绍了我们为了监控App的网络性能、页面性能和稳定性这三个核心性能指标而开发的APM系统,实践下来,发现APM系统在以下几个方面对比较有价值:

  • 让我们对线上App的实际运行的性能数据有了更加清晰直观的了解;

  • 各项核心指标的监控和性能日报对线上App的稳定运营提供保障;

  • 为我们各项性能优化提供了标准和数据支撑,按照标准去优化,优化之后有报表数据支撑;

  • 推动业务开发团队进行性能优化,让业务开发团队更加重视自己的产品性能质量;

本文介绍的只是APM系统的核心部分,实际上还有大量定制功能无法一一展开,比如告警和性能日报、自定义报表、各类专项性能等。希望我们在网络性能、页面性能和稳定性方面的实践经验对大家有所启发。

注:“携程技术”微信公众号后台回复“apm”,可下载讲师分享PPT。

【推荐阅读】

  • 近万字长文详述携程大规模应用RN的工程化实践

  • Node.js在携程的落地和最佳实践

  • 携程 Trip.com App 首页动态化探索

  • 加载速度提升15%,携程对RN新一代JS引擎Hermes的调研

  • 《携程技术2019年度合辑》,送给爱学习的你

 “携程技术”公众号

  分享,交流,成长

干货 | 携程无线APM升级实践相关推荐

  1. 干货 | 携程持久化KV存储实践

    作者简介 布莱德,携程软件技术专家:蔚浩,携程资深软件工程师:小董,携程技术培训生. 一.背景 过去几年,携程技术保障部门在Redis治理方面做了很多工作,解决了运营上的问题,在私有云上也积累了丰富的 ...

  2. 干货 | 携程 Web CI/CD 实践

    作者简介 西杰,携程软件技术专家,关注前端技术及其生态,致力于提升前端开发效能及质量. 一.背景 在携程的日常Web开发生命周期中,本地代码开发阶段可通过NFES框架(携程内部一个支持SSR框架,其中 ...

  3. 干货 | 携程机票Sketch插件开发实践

    作者简介 尹正波,携程机票研发部前端工程师,专注设计和开发的交叉领域,用系统和工具改进设计体验和交付. Sketch 是伴随移动应用程序崛起而流行的 UI 设计工具.2014年 Sketch V3 增 ...

  4. 干货 | 携程酒店安卓地图开发实践

    作者简介 亦枫,携程资深软件工程师,负责酒店业务 Android 客户端的相关研发工作. 当前大多数移动互联网 App 都会存在地图相关功能,尤其是 LBS(基于位置服务)相关的业务,依赖性更强,携程 ...

  5. 干货 | 携程RN渲染性能优化实践

    作者简介 佳璐,前端开发专家,关注前端框架.性能.质量.效率和新技术. 一.背景 随着 React Native 在前端业界规模性的应用越来越多,各大厂也对其渲染性能越来越看重. 渲染性能的主要评判指 ...

  6. 携程无线工程技术系列——从零打造携程无线持续交付平台 MCD 实践

    作者简介:携程无线基础工程团队高级经理,负责无线交付平台和基础服务研发.十多年的互联网从业经验,曾供职于 eBay 等互联网公司,研发经验丰富. 导语:携程 App 几乎承载着整个集团的所有业务形态, ...

  7. 干货 | 携程微服务体系下的服务治理之道和优化实践

    作者简介 HongLiang,携程高级技术专家,专注系统性能.稳定性.承载能力和交易质量,在技术架构演进.高并发等领域有丰富的实践经验. 一.背景 微服务架构在中大型互联网公司中被广泛应用,随着业务的 ...

  8. 干货 | 携程机票前端安卓虚拟机测试集群建设实践

    作者简介 Liang,携程研发总监,关注DevOps,前端&服务端质量保障.能效提升: Tony,携程资深测试经理,关注自动化测试框架及平台类工具开发. 一.背景 在携程内部业务高频率敏捷迭代 ...

  9. 干货 | 携程国际业务动态实时标签处理平台实践

    作者简介 Weiyi,携程资深数据开发,关注大数据相关技术,对大数据实时计算.流批一体等方面有浓厚兴趣: Hzhou,携程资深数据开发,关注大数据相关技术,对系统架构和实时处理等方面有浓厚兴趣: Ro ...

最新文章

  1. NBT:宏基因组二、三代混合组装软件OPERA-MS
  2. 转:【图文教程】创建Xcode自定义模板
  3. 音频光端机与电话光端机区别
  4. [css] Reset CSS和Normalize CSS的区别是什么?
  5. win7如何添加终端服务器,Windows7系统超级终端的添加方法 win7如何添加超级终端...
  6. Java高并发入门-线程初步(二)
  7. linux arm桌面程序,Electron 从零创建一个 Windows/OS X/Linux 的桌面可执行程序
  8. V 语言强势登顶 GitHub TOP1,欲取 Go 而代之?
  9. php查询mysql增加模板消息_php 实现发送微信模板消息
  10. ArcGIS软件气象数据插值教程
  11. Cortex-M3 (NXP LPC1788)之IIS控制器
  12. iOS 不能播放远程视频(Android 可以)的问题
  13. AM5SE-IS防孤岛保护装置如何解决分布式光伏发电过程中的影响?
  14. 庄子《天下》:道与术,取与予,利与害,方与圆,常与变,生与死
  15. CC2540F256RHAR
  16. LTE CQI/PMI 上报机制
  17. Unity加载进度条
  18. r语言中trifit怎么用_【r-介绍|分享】使用R进行生存分析
  19. [行人重识别论文阅读]Fine-Grained Shape-Appearance Mutual Learning for Cloth-Changing Person Re-Identification
  20. 请在mysql配置文件修sql-mode或sql_mode为NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTIT windows下设置mysql的sql_mode

热门文章

  1. 精排模型-从MLP到行为序列:DIN、DIEN、MIMN、SIM、DSIN
  2. 个人部署HRNet随记
  3. 冠珠瓷砖打造民族文化品牌,让中国陶成为中国潮
  4. 传感技术复习笔记(3)——电阻应变计式传感器
  5. querybuilder 排序_Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)...
  6. python课堂讨论_Python的课堂总结吧
  7. Python深度学习SC2(星际争霸2)AI
  8. 织梦重置mysql数据库密码忘记_忘记织梦管理员密码怎么修改
  9. raise ValueError(‘Only know how to handle PNG; with Pillow ‘ValueError: Only know how to handle PNG;
  10. 6个免费好用可替代Notepad++的记事本软件下载