结合MTA来走出打造app性能数据监控平台的最后一公里

2019-11-07 17:52:58 浏览数 (2)

背景

App前期的工作主要以业务开发为主,在开发阶段,我们比较关注的是如何能个快速迭代开发,当这个紧锣密鼓的阶段结束之后,大多数App会走向稳定运营的阶段了,那么在业务开发需求没有那么紧急的情况下,我们势必会找点其他的乐子了,比如,如何提升App的体验,当然这个就说得有点虚了,体验包括太多太多了,例如,在用户操作上讲究秒响应,在App耗电上要求处在同类App中的一个较少的层次,在安装包大小上别搞得太大,不然用户可能都不想安装,心理承受成本较高,在发送ugc上要求秒发,在内存占用上要求不要吃我手机太多内存,在冷启动的时候,别让我等太久以至于我失去耐心,在流量上要求别耗我太多,用户基本上也有一个心理预期,太多了可能觉得你是不是偷偷干了点啥,会卸载你,其实还有很多很多的指标可以来做用户体验。

我们发现,有一些指标是很容易跟踪,而有些需要经过一定时间的观察,分布分段观察,甚至是横向对比才能发现可优化的点的。

举个栗子,就说App的内存占用把,我们知道App的内存占用,并非是指启动一个App啥都不做,去测量,去计算得到的App的内存占用,用户一定不买账,相反它应该是用户使用我们的App,且经过一系列操作,光顾过多个页面,出现的一个较为稳定的峰值,当然,我并不认为我说的一定准确,如有更好的定义,可以交流。

那么,这样一个峰值,我们拿到了,请问,有优化的实际意义吗,我们认为它并没有,那么我们是不是要做一定的转化,换句话说,我们需要展开这个峰值,让他变成,一个个的分块,来看哪个分块是罪魁祸首,这才是我们需要找的优化点。

因此,我们知道,当一个整体数据变成不可琢磨时,我们需要细分这个数据,把他用阶段、类型等维度来划分,这样的数据便于我们找到性能上可优化的点。

让我们来理一理,我们需要完成这样一个性能数据监控系统,我们需要做哪些事情。

  1. 性能数据可衡量指标,嗯,重点在于可衡量。
  2. 性能数据上报,上报到什么地方
  3. 数据清洗,计算可复用中间结果,因为数据的上报量很多,一个百万日活的App,每天上报的数据少说也在几千万上亿的级别,所以存储在哪里是我们无法避免的一个问题。
  4. 计算出的可复用的中间结果存储在哪里。
  5. 管理端、日报生成的开发工作,来呈现数据。

好的,让我们一起来看看如何case by case的解决以上问题,并实现我们的性能数据监控系统。

性能数据收集

首先,我们要清楚我们关注的点有哪些,比如,就目前我们实现的点来说,有:

  1. 页面启动耗时
  2. App冷启动耗时
  3. 接口请求耗时
  4. 接口请求失败率
  5. 页面加载内存消耗[差分量]

这里,我们需要注意点是,收集到的一定是可衡量的指标,举例说明,页面内存消耗差分量,是指A页面进入B页面,此时内存的增量,我们最终以这个指标来衡量我们App的内存占用,因为我基于的是App的内存占用就是由一个个的页面的内存占用的组合,因为我们把App内存占用转化为了页面加载内存消耗差分量。

那么,我们上报的数据的格式是怎么样的呢?

这里也举个栗子说明,比如,我们上报的页面内存消耗的差分量,上报的一条原始数据为:

代码语言:javascript复制
{
"kv":{
"req_page_name":"xxxxActivity"
    },
"date":20191106,
"uuid":"xfefefsfsefsffesfsfes",
"memory_add":16
}

其中uuid是为了过滤重复上报,date表示哪天,req_page_name表示那个页面,memory_add,表示此页面被加载时的内存增长量。聪明的小伙伴肯定会说,这个指标可能需要继续细化,比如,这个页面内存增长可能分为图片消耗的内存,和网络数据解析消耗的内存,及其他。

完全没错,指标越精细化,越方便我们快速定位性能问题所在的点。

对于性能数据的收集,这里就不在一一赘述了,个人推荐使用matrix。我们就是参考了matrix的相关源码来做性能数据收集的。


数据上报

如果不知道TDW[腾讯数据仓库,海量数据计算就是爽]这个利器,这的确是一个非常头疼的问题,可问题是,即便我们知道TDW,难道我们要直接对接TDW,把数据往TDW里面写吗?我去了解了一下,虽然不是很复杂,申请一堆的权限就可以搞起了,但是真的有这个必要吗?

其实仔细想一想,我们已经介入了bugly,mta这样的一下平台了,我们App上报给他们的数据量也是很大,他们极有可能是往TDW存的,那我们可否利用这些平台上报我们自己定义的数据呢?

答案显然是可以的,我了解到MTA就具备我所需的条件:

1、支持自定义数据,参考这里

2、可以支持TDW给你应用对应数据的库表访问权限,需要找MTA那边的小伙伴开通权限,告知应用appid即可。

3、甚至他提供一下api接口,不过调研了下,对于我们目标作用并不是很大。

总的来说,前两点就完全够我们满足需求了,真的是正好瞌睡,就有人送枕头。


数据计算

数据计算的目的是为了利用收集上来的原始数据计算出一些可复用的数据模型。

我们上报的数据量是很大的,每次来这样一些操作:

代码语言:javascript复制
avg(xxx), 
count(distinct xxx,xxx,xxx) ,
group by ,
order by ,
left join,

这个耗时是很反人类的,因此,需要计算出一些可复用的数据模型,要完成这个操作,我们可以在TDW上配置计算任务,计算任务的作用就是做海量数据计算,那么计算出来的结果就可以存储到TDW上的临时表上。

举个栗子:我们计算页面加载内存增量时的脚本:

代码语言:javascript复制
 # 统计页面内存占用
    selectSql = '''
    SELECT
        cdate,
        id,
        kv,
        avg(du) as avg_du
    FROM
        teg_mta_intf :: ''' current_table '''
    WHERE
        ei = "page_did_appear_memory_consume" and cdate = ''' yestoday ''' and du >0
    group by id,kv,cdate order by avg_du desc;
    '''
    doInseretPageMemoryUse(tdw,selectSql)

def doInseretPageMemoryUse(tdw, selectSql):
    sql = '''CREATE TABLE if not EXISTS t_wangzhe_page_memory_use(
    id BIGINT COMMENT 'mta appid',
    cdate BIGINT COMMENT '流水日期,格式 YYYYmmdd',
    kv STRING COMMENT 'propertys',
    avg_du BIGINT COMMENT '内存消耗'
    )
    COMMENT '游戏人生页面内存占用'
    PARTITION BY LIST( cdate )
    (
        PARTITION default
    )
    STORED AS FORMATFILE;'''
    tdw.WriteLog("running SQL : "   sql)
    tdw.execute(sql)

    sql = '''insert table t_wangzhe_page_memory_use(cdate,id,kv,avg_du)  ''' selectSql
    tdw.WriteLog("running SQL : "   sql)
    tdw.execute(sql)

可以看到我们把计算结果存储到了TDW上自建的一张表上了,然后在配置一个出库任务出库到MySQL机器上就可以了。

TDW上的数据计算及中间可复用数据模型任务TDW上的数据计算及中间可复用数据模型任务

出库到MySQL的原因是为了我们的后台数据服务可以方便访问。

管理端等开发工作

到目前这个环节,我们已经了有可复用的数据模型了,数据就存储在MySQL上了,那么,接下来,我们需要做的是:

  1. 写一个后台server,暴露一些对外接口来查询这些数据模型,我使用的express,一个node的server。
  2. 在写一个精美的管理端,来呈现这些数据,我使用的element,一个vue的管理端框架

页面展示页面展示
下钻页面下钻页面

总结

王者人生性能数据监控系统的整体架构图可以用下图来描述:

系统的整体架构系统的整体架构

在数据收集的过程中因为平台的不同有着两套代码,但是,在实现数据所代表的意义都是一致的,这一点很关键。其次我们在wiki上定义了收集数据的指标的key,这样便于我们统一收集,统一分析。

MTA为我们提供了数据上报的入口和存储的途径,善于利用App已有的资源,使得我们少做了很多与需求业务不太相关但有不可或缺的工作,使得我们可以把有限的精力放在如何做更精细化、更准的性能监控平台上来。

0 人点赞