解决方案:应用性能前端监控,字节跳动这些年经验都在这了
优采云 发布时间: 2022-12-22 00:06解决方案:应用性能前端监控,字节跳动这些年经验都在这了
背景
自字节跳动发展至今,已经有数个数量级的庞大Web项目上线,服务于数亿用户。
随着用户数量的不断增长,对站点体验测量的需求也在不断增加,用户将产品与他们每天使用的体验最好的网站进行比较。 想要开始优化,首先要有相关的监测数据,才能对症下药。
性能是留住用户的关键。 大量的研究报告表明了绩效与企业绩效之间的关系。 性能不佳会导致您的网站失去用户、转化率和口碑。 错误监控使开发人员能够第一时间发现并修复问题。 仅仅依靠用户遇到问题和反馈是不现实的。 当用户遇到白屏或界面错误时,更多的人可能会重试几次,不耐烦干脆关掉你的网站。
字节跳动开发团队根据内部几十款产品的体验监控需求,逐步打磨出一个版本的性能监控平台。 经过不断的锤炼和沉淀,应用性能监控全链路版本在火山引擎上正式发布。 本文将重点介绍它是一个什么样的监控平台,可以帮助企业解决哪些痛点。
产品描述
应用性能监控全链路版是字节跳动旗下企业级技术服务平台,为企业提供针对应用服务质量、性能、自定义跟踪的APM服务。
该平台基于对海量数据的聚合分析,帮助客户发现多类异常问题,及时报警,并进行调配处理。 同时,平台提供丰富的归因能力,包括但不限于异常分析、多维分析、自定义报表、单点日志查询等,结合灵活的报表能力,可以了解数据的趋势变化各项指标。 更*敏*感*词*介绍参见各子监控服务的功能模块说明。
产品亮点
本部分仅从整个产品的角度描述应用性能监控全链路版的亮点。 更多技术亮点和优势,我们将在各个功能模块中为您详细讲解。
更低的接入成本:非侵入式SDK
接入SDK时,只需初始化几行代码即可成功接入。
npm install @apm-insight-web/rangers-site-sdk
// 在项目最开始的地方引入下面的代码
import vemars from '@apm-insight-web/rangers-site-sdk/private'
vemars('config', {
app_id: {{你的appid}},
serverDomain: {{私有化部署服务器地址}},
})
或者通过JavaScript脚本直接通过CDN访问:
(function(i,s,o,g,r,a,m){i["RangerSiteSDKObject"]=r;(i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)}),(i[r].l=1*new Date());(a=s.createElement(o)),(m=s.getElementsByTagName(o)[0]);a.async=1;a.src=g;a.crossOrigin="anonymous";m.parentNode.insertBefore(a,m);i[r].globalPreCollectError=function(){i[r]("precollect","error",arguments)};if(typeof i.addEventListener==="function"){i.addEventListener("error",i[r].globalPreCollectError,true);i.addEventListener('unhandledrejection', i[r].globalPreCollectError)}if('PerformanceLongTaskTiming'in i){var g=i[r].lt={e:[]};g.o=new PerformanceObserver(function(l){g.e=g.e.concat(l.getEntries())});g.o.observe({entryTypes:['longtask']})}})(window,document,"script","{{你的CDN地址}}","RangersSiteSDK");
window.RangersSiteSDK("config",{
app_id: {{你的app_id}},
serverDomain: {{私有化部署服务器地址}},
<p>
});
</p>
更丰富的异常场景还原能力
应用性能监控全链路版不仅帮您发现各种异常问题无死角,还提供丰富的现场还原能力,包括但不限于堆栈回溯、用户交互还原。
更灵活的取样方式以节省资金
应用性能监控全链路版为您提供采样配置,支持按功能模块和用户设置采样,帮助您节省事件量。
如此完备的性能监控平台,背后一定有一套成熟的方法论。 从平台设计之初,我们就做好了详细的技术方案设计和测量标准设计。 接下来,我将从更详细的角度来介绍这些设计以及它们背后的详细原理。
如何衡量 Web Experience 站点体验
首先,在网站体验方面,Web Vitals定义了LCP、FID、CLS指标,这些指标已经成为行业主流标准。
基于体验指标的长期优化和积累,最新的核心体验指标主要集中在加载、交互、视觉稳定性等方面。 加载速度决定了用户能否尽快访问视觉图像,交互速度决定了用户能否在心理上尽快感受到页面上的元素可操作,而视觉稳定性负责衡量视觉带来的负面影响用户页面的抖动。
归纳起来,有以下三个指标:
最大内容绘画 (LCP)
最大内容绘制,用于衡量加载性能。 该指标报告视口中可见的最大图像或文本块的渲染时间。 为了提供良好的用户体验,LCP分数最好保证在2.5秒以内。
第一输入延迟 (FID)
第一次输入滞后,用来衡量交互性。 FID 测量从用户与页面的第一次交互(例如,当他们单击链接、单击按钮或使用自定义 JavaScript 驱动的控件时)到浏览器实际能够开始响应该交互的时间,为了提供良好的用户体验,网站应努力将 FID 控制在 100 毫秒以内。
累积布局偏移 (CLS)
累积布局位移,用于衡量视觉稳定性。 CLS 是衡量页面整个生命周期中发生的每次布局更改的最大布局更改分数的指标。 为提供良好的用户体验,网站应力争 CLS 分数为 0.1 或更低。
错误监控
从错误监控的角度来看,当一个页面达到上亿访问量时,无论发布前经过了多少轮单元测试、集成测试、人工测试,都难免漏掉一些边缘操作路径测试,甚至偶尔出现难以重现的形而上学失败。 即使这些错误仅在 0.1% 的时间内发生,具有 1 亿访问量的站点也会导致用户经历数百万次故障。
这时候,一个完整的错误监控系统就派上用场了。
对于JavaScript错误、静态资源错误、请求错误,我们提供了错误数量、错误率、受影响用户数、受影响用户比例等宏观指标。 一目了然,我们可以关注剩余的错误及其对用户的影响,以协助开发人员尽快修复问题。
同时,对于请求的监控,为了进一步保证用户获取数据的体验,我们进一步细化了慢查询相关的请求成功率和指标。
SDK采集
有了这些衡量标准,我们再来看看SDK是如何实现这些标准的。
需要采集哪些指标? 如何采集这些指标?
RUM指标的采集主要依赖Event Timing API进行衡量。
以FID指标为例,首先创建一个PerformanceObserver对象,*敏*感*词*第一个输入事件。 *敏*感*词*到第一个输入的事件后,使用Event Timing API从事件的开始处理时间减去事件发生时间得到FID。
// Create the Performance Observer instance.
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
const FID = entry.processingStart - entry.startTime;
console.log("FID:", FID);
}
});
// Start observing first-input entries.
observer.observe({
type: "first-input",
buffered: true,
<p>
});
</p>
Navigation Timing指标可以通过PerformanceTiming接口获取,以加载时间的计算为例:
function onLoad() {
var now = new Date().getTime();
var page_load_time = now - performance.timing.navigationStart;
console.log("User-perceived page loading time: " + page_load_time);
}
JS Error 指标,通过 window.onerror 回调函数来监控 JavaScript 运行时错误:
window.onerror = function (message, source, lineno, colno, error) {
// 构造异常数据格式并上报
};
通过 unhandledrejection 事件*敏*感*词* Promise 拒绝异步错误:
window.addEventListener("unhandledrejection", (event) => {
// 构造异常数据格式并上报
});
请求状态码,可以通过覆盖window.fetch和XMLHttpRequest对象实现监控。 以覆盖fetch为例,简化代码如下:
const _fetch = window.fetch;
window.fetch = (req: RequestInfo, options: RequestInit = {}) => {
// 省略一些逻辑……
return _fetch(req, options).then(
// 成功
(res) => {
// 上报成功请求信息
return res;
},
// 失败
(res) => {
// 上报失败请求信息
return Promise.reject(res);
}
);
};
服务器处理
SDK数据采集完成后,会交给服务端进行采集、清洗、存储。
服务端收到数据后,进行实时纬度分析补全、堆栈反分析等清洗任务,根据不同平台的产品功能,分为不同类型的存储:
解决方案:Google如何对待采集站
前几天我提到谷歌要对采集站采取行动,现在看来行动来得比预定的要早。
一般采取的措施如下:
谷歌搜索,将大量重复的内容放入搜索的补充结果中。
Google 搜索,从搜索索引中删除一些内容。
Google AdSense,对于那些网站,它的smartprice会起到很大的作用,直接的结果就是价格会比原创的低。 这就是为什么很多站长抱怨发布者论坛单价不断下降的原因。
Google AdSense 还将处理那些严重侵犯版权或与 Google 先前已通知的内容相关的采集网站。 这部分主要是版权问题,我上面也提到了。
Google AdWords,对于采集投放广告的广告商来说,他们的landing page甚至Landing Site的分数都会很低,所以他不得不支付更多的钱来展示广告。 这部分将在广告评估期间完成。
以上只是David Yin的部分所想所知。 我想很多谷歌用户也会猜测,谷歌会采取这样那样的措施来加强对内容质量的要求。