一、背景
爱番番大前端整体面临以下问题:
-
Metrics:URL的RED指标不全。URL不全,ERROR缺失,Duration分位置缺失。整体实效性为T+1。无法及时感知问题。只对基本页面级别的读操作进行了监控。
-
Tracing:Trace无法全端串联,直接影响具体case的跟进。无前端Trace。
-
Logging:无Log。Sentry的Error信息目前仅PC接入。且未进行实际使用;和trace无法打通。
-
报警:对于异常数据缺乏有效报警。
二、目标
-
Metrics目标:RED指标,自定义Metrics
-
Tracing目标:全端单动作追踪
-
Logging目标:Error级别Log具备。单Traceid和Log能够实现串联
2.1 核心目标
从全局问题出发,能够洞察统计性的页面url真实RED指标,以及可以做操作流任意阶段之间的统计性耗时分析。从个案问题出发,能够基于用户id进行任意一次全端调用链追踪。
具体地:
-
页面级别性能监控。可包含条件检索和正常页面刷新。包含RED
-
能够基于用户id进行任意一次全端调用链追踪。
-
可分析一个操作流任意阶段之间的统计性耗时。
-
准实时呈现。数据延时小于5min。
-
可区分来源、地域、设备等核心信息
-
写请求性能监控。包含新建、编辑、删除。包含RED
2.2 目标抽象
本质上,抽象为AggrEvent、Event、Trace、Span四个概念。Transaction用来做纯埋点,此处暂不需要。
-
带TraceID(可被覆盖)和TimeStamp信息的Event
-
全端Trace下的调用链。本质上是前端的Event链路 + 服务端的Span链路串联而成。
-
考虑到批量传输性能。采用AggrEvent进行聚合发送。
三、 名词解释
-
RED:RED方法是Weave Cloud在基于Google的“4个黄金指标”的原则下结合Prometheus以及Kubernetes容器实践,细化和总结的方法论,特别适合于云原生应用以及微服务架构应用的监控和度量。主要关注以下三种关键指标:
- (请求)速率:服务每秒接收的请求数。
- (请求)错误:每秒失败的请求数。
- (请求)耗时:每个请求的耗时。
- optid(operate-id):一个操作唯一对应的一个id。比如一次刷新,一次修改。
- reqid(request-id):单次请求唯一对应的一个id。如果重试,则reqid设置为新id。一个optid可能会存在多个reqid。
- tid(tracing-id):贯穿服务端端调用链的唯一id。
- optType: 某一类操作定义。比如一次刷新,一次修改。
四、目标拆解
4.1 Why
4.1.1 为什么要做大前端监控体系?
获取用户行为以及跟踪产品在用户端的使用情况,并以监控数据为基础,指明产研优化的方向。
4.1.2 收益是什么?
-
Metrics:对各端各页面各场景RED指标准实时分析、可视化呈现,打破前端监控黑盒
-
Tracing:打通前后端调用链,能够针对任意case进行前后端链路分析,让前端性能优化有的放矢
-
Logging:对各端运行时错误进行实时监控报警,能通过日志最大程度还原用户现场并定位问题,提升前端页面稳定性
4.2 What
4.2.1 监控什么端?
爱番番现有产品各端:web,h5(浏览器、webview),Android,iOS,客户端,小程序
4.2.2 监控什么方向
(1) 数据监控
数据监控,顾名思义就是监听用户的行为。常见的数据监控包括:
-
PV/UV:PV(page view),即页面浏览量或点击量。UV:指访问某个站点或点击某条新闻的不同IP地址的人数
-
用户在每一个页面的停留时间
-
用户通过什么入口来访问该网页
-
用户在相应的页面中触发的行为
统计这些数据是有意义的,比如我们知道了用户来源的渠道,可以促进产品的推广,知道用户在每一个页面停留的时间,可以针对停留较长的页面,增加广告推送等等。
该方向主要为业务服务,目前职责定位更符合神策埋点系统。
(2) 性能监控
性能监控指的是监听前端的性能,主要包括监听网页或者说产品在用户端的体验。常见的性能监控数据包括:
-
不同用户,不同机型和不同系统下的首屏加载时间
-
白屏时间
-
http等请求的响应时间
-
静态资源整体下载时间
-
页面渲染时间
-
页面交互动画完成时间
这些性能监控的结果,可以展示前端性能的好坏,根据性能监测的结果可以进一步的去优化前端性能,比如兼容低版本浏览器的动画效果,加快首屏加载等等。
(3) 异常监控
产品的前端代码在执行过程中也会发生异常,因此需要引入异常监控。及时的上报异常情况,可以避免线上故障的发上。虽然大部分异常可以通过try catch的方式捕获,但是比如内存泄漏以及其他偶现的异常难以捕获;
爱番番目前采用sentry进行错误日志采集。
4.2.3 监控什么内容
1.web
类别
内容
页面分析
具体丰富的页面指标,提供如服务器端响应时间、网络延时、DOM解析和页面渲染时间等性能指标
帮助研发更快捷的定位服务端、客户端的页面问题
Ajax请求
获取用户访问过程,页面发出的所有Ajax请求URL、引用页面URL,监控某一Ajax请求的响应时间、回调时间、上传数据量、下载数据量以及响应过程中服务器返回的错误
JS error
代码级定位出错页面或者脚本URL,引用页面URL,出错的行列信息、堆栈等信息,通过sourceMap定位源码文件,通过pageId,operateId以及tid最大限度还原上下文
监测Web App中JS错误的数量,各浏览器出错百分比和JS错误率随时间变化的趋势
浏览器监测
统计不同版本浏览器和浏览器类型的平均页面加载时间和吞吐率
提供基于多平台浏览器性能分析,兼容性分析
慢页面追踪
抓取加载时间超过设定阈值的页面上的元素信息,及每个元素的TCP建连、首包及剩余包等所需时间
详细定位页面上的哪些元素的加载拖慢了页面的响应,为优化用户体验提供依据
2.其他端:
h5(浏览器、webview)
统计从端点击开始,到指定页面渲染全流程时间分布,包括(容器耗时,框架耗时,网络耗时,渲染耗时等)。
统计NPJS框架自身稳定性,以及各个阶段耗时。
统计任意多个操作各个时间断耗时。
iOS,Android
现在使用百度移动端性能中台,功能基本满足爱番番监控、报警功能;
移动端监控指标主要为 卡顿和崩溃,目前有崩溃堆栈信息日志;暂无交互时长分析(xray平台有,手百性能中台没有)
http://performance.baidu.com/
PC客户端
electron监控方案参考WEB版
四、方案调研
自建or接入其他平台?
业务埋点采买神策。
性能监控平台:
厂内:
性能中台 http://performance.baidu.com/
日志中台 http://app.baidu-int.com/
目前日志中台可以接入日志,但是需求是前端页面的性能指标,属于性能平台范围,目前性能平台无前端性能指标建设。
性能中台的定位主要是针对native,当前通用能力主要是崩溃、卡顿、端异常、Flutter异常、日志回捞等,其他的一些能力主要在手百、或者相关SDK上,还未对外输出。经沟通暂不考虑支持前端性能监控。
厂外:性能监控主流收费平台:
-
ONEAPM https://www.oneapm.com/solutions/qualityacceptance.html
-
听云 https://www.tingyun.com/
-
性能魔方 http://www.mmtrix.com/imonitor
-
监控宝 https://www.jiankongbao.com/
收费平台功能大同小异,均能满足前端基础性能监控需求。
优点:有较为成熟的解决方案,能快速满足多端性能监控基本需求;
缺点:
-
收费
-
无法与部门现有后端APM体系打通
-
无法满足特定case分析需求
结论:复用神策埋点SDK存储,上报能力及通路,进行SDK二次封装;自建日志服务及展示系统。
Metrics:对各端各页面各场景RED指标准实时分析、可视化呈现,打破前端监控黑盒
Tracing:打通前后端调用链,能够针对任意case进行前后端链路分析,让前端性能优化有的放矢
Logging:对各端运行时错误进行实时监控报警,能通过日志最大程度还原用户现场并定位问题,提升前端页面稳定性
PV/UV:PV(page view),即页面浏览量或点击量。UV:指访问某个站点或点击某条新闻的不同IP地址的人数
用户在每一个页面的停留时间
用户通过什么入口来访问该网页
用户在相应的页面中触发的行为
不同用户,不同机型和不同系统下的首屏加载时间
白屏时间
http等请求的响应时间
静态资源整体下载时间
页面渲染时间
页面交互动画完成时间
类别
|
内容
|
页面分析
|
具体丰富的页面指标,提供如服务器端响应时间、网络延时、DOM解析和页面渲染时间等性能指标
帮助研发更快捷的定位服务端、客户端的页面问题
|
Ajax请求
|
获取用户访问过程,页面发出的所有Ajax请求URL、引用页面URL,监控某一Ajax请求的响应时间、回调时间、上传数据量、下载数据量以及响应过程中服务器返回的错误
|
JS error
|
代码级定位出错页面或者脚本URL,引用页面URL,出错的行列信息、堆栈等信息,通过sourceMap定位源码文件,通过pageId,operateId以及tid最大限度还原上下文
监测Web App中JS错误的数量,各浏览器出错百分比和JS错误率随时间变化的趋势
|
浏览器监测
|
统计不同版本浏览器和浏览器类型的平均页面加载时间和吞吐率
提供基于多平台浏览器性能分析,兼容性分析
|
慢页面追踪
|
抓取加载时间超过设定阈值的页面上的元素信息,及每个元素的TCP建连、首包及剩余包等所需时间
详细定位页面上的哪些元素的加载拖慢了页面的响应,为优化用户体验提供依据
|
自建or接入其他平台?
业务埋点采买神策。
性能监控平台:
厂内:
性能中台 http://performance.baidu.com/
日志中台 http://app.baidu-int.com/
目前日志中台可以接入日志,但是需求是前端页面的性能指标,属于性能平台范围,目前性能平台无前端性能指标建设。
性能中台的定位主要是针对native,当前通用能力主要是崩溃、卡顿、端异常、Flutter异常、日志回捞等,其他的一些能力主要在手百、或者相关SDK上,还未对外输出。经沟通暂不考虑支持前端性能监控。
厂外:性能监控主流收费平台:
-
ONEAPM https://www.oneapm.com/solutions/qualityacceptance.html
-
听云 https://www.tingyun.com/
-
性能魔方 http://www.mmtrix.com/imonitor
-
监控宝 https://www.jiankongbao.com/
收费平台功能大同小异,均能满足前端基础性能监控需求。
优点:有较为成熟的解决方案,能快速满足多端性能监控基本需求;
缺点:
-
收费
-
无法与部门现有后端APM体系打通
-
无法满足特定case分析需求
结论:复用神策埋点SDK存储,上报能力及通路,进行SDK二次封装;自建日志服务及展示系统。
五、方案设计 (web)
1、采集
(1)埋点SDK
基于神策SDK进行二次封装
统一封装埋点SDK,通过npm包形式进行版本管理;使用方在公共模块对埋点SDK进行初始化。
增加无侵入性能采集能力,提供采样率配置等可配置扩展能力。
参考接口文档
(2)通用统计指标(参考听云)
指标
统计方式
白屏
用户浏览器输入网址后至浏览器出现文字或1px图片所花费时间。计算规则:优先使用Chrome、IE提供的firstPaintTime,没有获取到计算head中link、script脚本下载的最长时间。
首屏
用户浏览器首屏内所有的元素呈现所花费时间。计算规则:寻找首屏区域内的所有图片,计算最长加载时间得到首屏时间。
可交互
功能可以使用的时间,也指domready时间。计算公式:可交互=Navigation Timing API domContentLoadedEventStart – fetchStart。
完全加载
页面完全加载总时间。指从NavigationStart事件开始到LoadEventEnd事件结束,计算公式:LoadEventEnd-NavigationStart
HTML加载
指主HTML文件从DNS解析到加载完且不包含排队时间和应用服务器响应时间,即包含DNS,TCP建连,Request和Response,计算公式:responseEnd-domainlookupStart-排队时间-应用服务器响应时间
页面渲染
指从responseEnd事件开始到loadEventEnd结束,包含DOM解析和资源加载,计算公式:LoadEventEnd-responseEnd
DOM解析
指从responseEnd事件开始到DomContentLoadedEventEnd事件结束,计算公式:DomContentLoadedEventEnd-responseEnd
资源加载
指从DomContentLoadedEventEnd事件开始到loadEventEnd事件结束,计算公式:loadEventEnd-DomContentLoadedEventEnd
JS错误率
出现JS错误的比例。JS错误包含Javascript错误代码和位置信息。
服务端响应时间
服务器响应时间是指应用服务器处理请求所消耗的时间,即应用响应时间,等于请求到达应用服务器到应用代码执行完成并输出响应信息的时间。(需要通过Server探针自动注入方式嵌码,否则服务器响应时间为零)
AJAX请求响应时间
所有Ajax请求时间在时间轴的投影合并的总耗时
unload
卸载当前页面的耗时,计算公式:unloadEnd-unloadStart
Redirect
页面重定向操作所消耗的时间,计算公式:redirectEnd-redirectStart
Cache
取缓存数据的耗时,计算公式:domainLookupStart-fetchStart
DNS
通过域名解析服务(DNS),将指定的域名解析成IP地址的消耗时间。
TCP建连时间
浏览器和WEB服务器建立TCP/IP连接的消耗时间。当元素下载完成后,浏览器可能会根据服务器返回的结果保持此连接,而不是完全关闭此连接。当监测节点再次和相同的服务器建立连接时,会复用此连接,对应消耗时间可能为0。此指标即为TCP/IP连接三次握手的前二次握手的时间(从IE发送TCP包SYN到收到服务器返回的TCP包SYN ACK的时间),第三次握手时间(从IE发送TCP包ACK到服务器接收此TCP包的时间)不计算在内。
排队时间
排队时间指服务器端的请求阻塞时间,即请求从Web前端服务器(例如Apache, nginx或F5负载均衡设备)到达应用服务端的时间。
首包时间
从开始页面请求到浏览器开始接收到HTML代码的时间,不包括排队时间和服务器端的时间,计算公式:responseStart-connectEnd -排队时间-服务器响应时间
剩余包时间
从responseStart事件开始到responseEnd事件结束,计算公式:responseEnd-responseStart
首次渲染时间
从导航到页面首次渲染消耗的时间,计算公式:firstPaintTime-navigationStart(又名:白屏时间,firstPaintTime)
首次交互时间
从用户的第一个动作发生时间 – navigationStart,其中动作包括:点击,按键,滚动鼠标。
自定义加载时间
(用户可感知时间)
每个页面都可以设置一个用户自定义的加载时间性能指标。计算方式为路由切换时间至主动调用sdk ready方法时间差值
AJAX平响时间
平均每次AJAX请求的响应时间
AJAX传输数据量
单位KB,平均每次AJAX请求的数据传输量(上传+下载字节数)
AJAX回调时间
平均每次AJAX请求的回调时间(回调时间是指当数据从服务器传到客户端之后,本地代码调用这些数据做相应的处理,可以理解为本地执行时间)
客户端时间
从请求某资源到下载完过程中,没有出现网络传输的时间片段之和,比如DNS-TCP建连,之间的切换需要消耗CPU来调度,这就可能会产生很短的时间空隙
事件平均响应时间
操作请求完成时间。
统计方式,通过performance API
https://www.w3.org/TR/navigation-timing/
Core Web Vitals(https://web.dev/vitals/)
核心指标
metrics
描述
含义
TTFB
time to first byte
从请求到数据返回第一个字节所消耗时间
TTI
Time to Interactive (TTI)
DOM树构建完毕,可绑定事件
DCL
DOMContentLoaded
HTML文档完全加载解析完成
L
onLoad
依赖资源全部加载完毕
FP
first paint
第一个像素点绘制完成时间
FCP
First contentful paint (FCP)
首次绘制非空白节点时间
FMP
first meaningful paint
首次有意义绘制(需要自定义)
LCP
lLargest contentful paint (LCP)
在视口中最大的页面元素加载时间
FID
First input delay (FID)
用户首次和页面交互到页面响应的时间
指标
|
统计方式
|
白屏 |
用户浏览器输入网址后至浏览器出现文字或1px图片所花费时间。计算规则:优先使用Chrome、IE提供的firstPaintTime,没有获取到计算head中link、script脚本下载的最长时间。
|
首屏 |
用户浏览器首屏内所有的元素呈现所花费时间。计算规则:寻找首屏区域内的所有图片,计算最长加载时间得到首屏时间。
|
可交互 |
功能可以使用的时间,也指domready时间。计算公式:可交互=Navigation Timing API domContentLoadedEventStart – fetchStart。
|
完全加载 |
页面完全加载总时间。指从NavigationStart事件开始到LoadEventEnd事件结束,计算公式:LoadEventEnd-NavigationStart
|
HTML加载 |
指主HTML文件从DNS解析到加载完且不包含排队时间和应用服务器响应时间,即包含DNS,TCP建连,Request和Response,计算公式:responseEnd-domainlookupStart-排队时间-应用服务器响应时间
|
页面渲染 |
指从responseEnd事件开始到loadEventEnd结束,包含DOM解析和资源加载,计算公式:LoadEventEnd-responseEnd
|
DOM解析 |
指从responseEnd事件开始到DomContentLoadedEventEnd事件结束,计算公式:DomContentLoadedEventEnd-responseEnd
|
资源加载 |
指从DomContentLoadedEventEnd事件开始到loadEventEnd事件结束,计算公式:loadEventEnd-DomContentLoadedEventEnd
|
JS错误率 |
出现JS错误的比例。JS错误包含Javascript错误代码和位置信息。
|
服务端响应时间 |
服务器响应时间是指应用服务器处理请求所消耗的时间,即应用响应时间,等于请求到达应用服务器到应用代码执行完成并输出响应信息的时间。(需要通过Server探针自动注入方式嵌码,否则服务器响应时间为零)
|
AJAX请求响应时间 |
所有Ajax请求时间在时间轴的投影合并的总耗时
|
unload |
卸载当前页面的耗时,计算公式:unloadEnd-unloadStart
|
Redirect |
页面重定向操作所消耗的时间,计算公式:redirectEnd-redirectStart
|
Cache |
取缓存数据的耗时,计算公式:domainLookupStart-fetchStart
|
DNS |
通过域名解析服务(DNS),将指定的域名解析成IP地址的消耗时间。
|
TCP建连时间 |
浏览器和WEB服务器建立TCP/IP连接的消耗时间。当元素下载完成后,浏览器可能会根据服务器返回的结果保持此连接,而不是完全关闭此连接。当监测节点再次和相同的服务器建立连接时,会复用此连接,对应消耗时间可能为0。此指标即为TCP/IP连接三次握手的前二次握手的时间(从IE发送TCP包SYN到收到服务器返回的TCP包SYN ACK的时间),第三次握手时间(从IE发送TCP包ACK到服务器接收此TCP包的时间)不计算在内。
|
排队时间 |
排队时间指服务器端的请求阻塞时间,即请求从Web前端服务器(例如Apache, nginx或F5负载均衡设备)到达应用服务端的时间。
|
首包时间 |
从开始页面请求到浏览器开始接收到HTML代码的时间,不包括排队时间和服务器端的时间,计算公式:responseStart-connectEnd -排队时间-服务器响应时间
|
剩余包时间 |
从responseStart事件开始到responseEnd事件结束,计算公式:responseEnd-responseStart
|
首次渲染时间 |
从导航到页面首次渲染消耗的时间,计算公式:firstPaintTime-navigationStart(又名:白屏时间,firstPaintTime)
|
首次交互时间 |
从用户的第一个动作发生时间 – navigationStart,其中动作包括:点击,按键,滚动鼠标。
|
自定义加载时间(用户可感知时间)
|
每个页面都可以设置一个用户自定义的加载时间性能指标。计算方式为路由切换时间至主动调用sdk ready方法时间差值
|
AJAX平响时间 |
平均每次AJAX请求的响应时间
|
AJAX传输数据量 |
单位KB,平均每次AJAX请求的数据传输量(上传+下载字节数)
|
AJAX回调时间 |
平均每次AJAX请求的回调时间(回调时间是指当数据从服务器传到客户端之后,本地代码调用这些数据做相应的处理,可以理解为本地执行时间)
|
客户端时间 |
从请求某资源到下载完过程中,没有出现网络传输的时间片段之和,比如DNS-TCP建连,之间的切换需要消耗CPU来调度,这就可能会产生很短的时间空隙
|
事件平均响应时间 |
操作请求完成时间。
|
metrics
|
描述
|
含义
|
TTFB
|
time to first byte
|
从请求到数据返回第一个字节所消耗时间
|
TTI
|
Time to Interactive (TTI)
|
DOM树构建完毕,可绑定事件
|
DCL
|
DOMContentLoaded
|
HTML文档完全加载解析完成
|
L
|
onLoad
|
依赖资源全部加载完毕
|
FP
|
first paint
|
第一个像素点绘制完成时间
|
FCP
|
First contentful paint (FCP)
|
首次绘制非空白节点时间
|
FMP
|
first meaningful paint
|
首次有意义绘制(需要自定义)
|
LCP
|
lLargest contentful paint (LCP)
|
在视口中最大的页面元素加载时间
|
FID
|
First input delay (FID)
|
用户首次和页面交互到页面响应的时间
|