去哪儿网快速App开发及问题解决平台实践

1,359 阅读7分钟

内容来源:2017年5月6日,去哪儿网平台事业部客户端技术总监张子天在“携程技术沙龙——移动开发工程实践与性能优化”进行《去哪儿网快速App开发及问题解决平台实践》演讲分享。IT大咖说作为独家视频合作方,经主办方和讲者审阅授权发布。
阅读字数:2211 | 4分钟阅读


摘要

本次分享主要介绍去哪儿的客户端团队在大规模多团队多APP的情景下,如何快速简单可靠地维护自己的产品。

通过实际场景重现,介绍用户行为跟踪和网络数据交互的监控的相关内容,解决目前业界难以处理的方案如无埋点统计的收集与提取,网络监控的Hook方案及无线远端测试等。

通过介绍去哪儿在解决产品和用户问题的过程,介绍相关系统的使用和技术内幕,启发大家在多前后端、跨团队的场景如何更快的开发和维护APP,迅速定位解决问题。

嘉宾演讲视频和PPT地址

t.cn/RChIMfH

APP闪退

很多普通用户在经历APP闪退的时候,往往无法准确表述出APP出现的问题,最多只能告知我们机型或用户账号,以至于我们能了解到的信息非常少。

故障处理办法

我们最需要知道的信息是用户闪退的时间、闪退的具体页面和闪退的原因。但这些信息用户一般都不能提供,所以这时我们就只能到各个系统里查询日志、拉故障处理群,去“猜”故障的原因。

角色变化

因为在业务过程中整个工作团队发生了很大的变化。最初遇到问题,几个人讨论一下基本就能解决;随着业务发展日渐庞大,从单个团队分成了多个团队;再到后来,不同开发方式的出现导致每个人的职责和对APP的了解都非常片面,所以大家不能一目了然地知道问题出在哪儿。

页面刷不出来

关于页面刷不出来的问题,我们目前最新的做法是进行用户的流程监控。



从图中可以看见用户具体进行了什么操作、在什么时间做了什么事情。

我们称之为“用户细查”。

每个页面还能打开它具体请求的情况,看到请求耗时、时间线,甚至可以打开每个请求看到接口请求的后台系统经过哪些环节。

现在可以通过用户细查分析问题出现在哪个环节上,只需把对应环节的相关负责人召集到一起就能解决问题,不会像传统办法那样耗时很长,还消耗大量人力。

这里涉及到的技术细节就有以下几种:

如何知道用户的交互行为和渲染变化;

如何知道用户的网络请求和时间线;

如何能还原用户的场景;

怎样才能不影响业务代码的开发。

涉及到的系统——“筋斗云”

QAV是交互统计,QACR是异常监控,QTrace是用于监控网络请求的整个流向。


交互行为和渲染变化

先从交互行为说起,首先要看监控的事件类型。事件类型分为APP生命周期事件、页面切换事件和交互事件三种。

定位控件在早年是用view-id的方式去做的,但这个方式非常的不靠谱,所以在那个年代经常会用手动埋点的方式进行操作。

后来有了坐标的方式,其实也没有比view-id好很多,尤其是在Andriod上,会因为各种机型不同、屏幕尺寸不一样而不准确。

在用了xpath一段时间后发现,它在Andriod上不够稳定。体现在不同系统ROM里,它会对整个view数自行做一些厂商里定制的内容,甚至还有一些会自动增删内容。

所以我们在xpath基础上做了一些改进,对xpath基础的页面和布局的定义采用了自定义格式去做。

无论采取哪种方式,数据都会有变化,所以我们需要一个合并数据项。

各个平台xpath的样式是不同的。


在业务的开发过程中不能让它手动埋点,所以要采取Hook的方式。


Hook在不同平台上有不同的方式。在IOS上可以用Runtime去做,而在Andriod上则要采用不一样的方式。

Andriod上其实也能用Runtime的方式做,但不是很好。因为它不是真正的运行期的Hook,它需要预插桩,对运行的效率会有影响。

所以运行期Hook使用的是InstantRun,在构建期Hook使用的是JavaAgent。


在IOS上注入代码很简单,在Andriod上就比较复杂了。


在构建过程中,Hook出构建的脚本,把所有预埋点加入Dex再打包,打完包的时候代码已经在真正输出的代码Dex里了。


这里分为三部分,一部分是Agent,一个是Gradle插件,以及真正要修改插入内容的部分。

插入内容部分就是网络部分的监控以及用户行为上的监控,这些相对于Hook来说是业务层,所以我们把它叫做Dex。

Agent本身是用来做Hook。


再来看一下我们都Hook了哪些内容。最基础的网络部分就是请求的时间、状态,以及当前网络是Wifi还是4G。

注入几个数据。

网络会根据不同的使用去注入不同的类型。因为一些历史遗留问题或第三方问题,必须要采用到不同网络请求的框架。

在react-native里,会直接在react-native的框架层注入Hook的方案。

将各项数据聚合

如何并发串联数据

我们会有一个绑定用户行为与网络请求的id。每个用户的交互行为都会生成一个id,下一次有网络数据的时候会把这个id带上去,这样哪个交互行为触发了用户请求,就能把它们关联在一起。

Uuid用来做接口的调用栈的串联。每经过一层都会加一个自己的标识,这样就可以追踪到整个网络调用栈的情况。

校正过的time排序是用来把前面所有的行为让它以一个正确的顺序排列在一起。


所有用户日志统一以客户端本身的时间进行排序。

日志上传

我们会把交互日志和网络请求日志压缩打包后再上传。

崩溃或卡顿等异常日志实时上传。


这一套系统开发出来是为了满足开发、测试、发布、监控这一个完整流程来做的,可以保证用最少的人力做最多的事。

冰山一角——绑定数据项

绑定数据项就是给控件一个比较人性化的名字,可以由非工作人员来完成。绑定完之后可以在日志行为中看到用户操作。

这样就极大减少了开发过程中对于统计类需求消耗的时间。也避免了网络日志只有程序员看得懂的尴尬,可以让它自主地进行操作。

冰山一角——崩溃聚合

我们发现外面主流做收集的厂商往往不能更完整地收集到所有需要的错误,我们是通过一整套的方式把它们收集在一起。


总结

我们是从数据、测试、发布、监控这几个环节把所有事情打包在一起,提供给业务人员,给他们一个友善的开发环境。

我今天的分享就到这里,谢谢大家!