编译整理|TesterHome社区
多年来,检测、预防和解决性能退化一直是 Pinterest 的标准做法。多年来,我们看到许多示例都表明,性能优化和退化导致业务指标发生重大变化。这些具体示例激励我们优化和保持性能。特别是,对抗退化被列为优先事项,因为我们无数次看到,几个月辛苦获得的优化成果很容易因一次退化而化为乌有。通常,退化来自一行代码,花一点时间更改实现即可让我们回到基线。下面简要概述一下 Pinterest 的性能计划。
Pinterest 的绩效计划
绩效指标
虽然性能团队会记录和监控许多性能指标,但我们的目标是一组自定义指标,我们称之为 Pinner Wait Time (PWT)。每个关键页面都定义了一个 PWT,用于跟踪页面上最重要的元素。例如,在 Pin 特写页面上,我们会跟踪加载大型英雄图像以及将 Pin 保存到您的图板上的按钮所需的时间。
图 1:英雄图像和保存按钮作为 Pin 特写页面的 PWT 指标的一部分进行跟踪
在 Web 方面,核心 Web 指标已加入我们的 PWT 指标,成为我们保护和优化的顶级性能指标。它们一直是我们大力优化的目标,并已被添加到我们的监控仪表板、A/B 实验框架和每个 diff 性能集成测试中,以进行回归保护。
所有权
性能团队拥有内部性能日志库、数据工作流、监控仪表板和性能工具,但指标本身由表面拥有团队负责。表面拥有者的职责包括监控指标的健康状况、做出权衡决策以及应对回归。性能团队定期与每个表面拥有团队同步,以在这些职责方面提供尽可能多的支持。
绩效预算
为了控制性能,表面所有者有责任维持其性能指标的基线。这意味着,在年底,他们的性能指标应该等于或低于年初的水平。虽然性能团队将帮助确保尽可能调查和缓解任何性能回归问题,但表面所有者最终是关键业务指标和性能指标之间权衡决策的驱动者。这些权衡决策通常是在发布 A/B 实验时做出的,但也可以在发布更改之前或之后做出(例如,当 PR 添加必要的模块导致 JS 包大小回归时,或者某种类型内容的分布增加导致生产中不可避免的回归时)。
关于 Pinterest 的绩效计划还有很多可以说的,因为该计划背后的流程多年来已经非常成熟,强大的绩效文化的价值也不容低估,但本文将重点介绍我们专门用于回归检测的工具和流程。
接下来,我们将讨论我们为网络性能指标实施的实时、真实用户监控。这些监控图表对于回归警报和执行根本原因分析至关重要。
实时真实用户监控
多年来,对抗回归一直是 Pinterest 的首要任务。下面我们将讨论如何使用来自真实用户的实时指标来监控和调查桌面和移动网络的 Pinner 等待时间和核心 Web 重要指标中的回归。这些实时图表对于回归警报和根本原因分析非常有用。
警报
以前,我们的警报和 Jira 票证是基于每日汇总的七天移动平均值。将我们的警报和回归调查流程迁移到基于实时图表的基础上,为更快地解决回归问题铺平了道路,原因如下:
1.立即可用且时间间隔更细的数据意味着可以更快、更准确地检测到回归。
更细化的时间间隔使我们能够更清楚地看到峰值,因为它们通常发生在内部更改推出所需的短时间内(通常少于 30 分钟)。
此外,当使用前两周的数据作为比较基线时,回归更容易被检测到。正常的每日和每周模式的峰值和下降不会触发警报,因为当前值和前几周之间的差值不会改变。只有当回归峰值超过前两周同一时间和同一星期的最大值时,才会触发警报。回归持续 30 分钟后会触发警告警报,而回归持续数小时后会触发伴随 Jira 票证的关键警报。
图 2:警报基于当前值与同一时间段内前两周的最大值之间的差值
2. 回归的明确开始时间显著增加了导致回归的根本原因的可能性(有关此内容的更多详细信息,请参阅下面的“根本原因分析”)。
3. 在发布后立即恢复或更改有问题的更改要容易得多。一旦更改发布时间较长,就会建立各种依赖关系,并使恢复或更改变得更加棘手。
根本原因分析
对于回归,我们的实时图表在根本原因分析中起着关键作用,因为它们使我们能够将生产回归的开始时间缩小到分钟。
我们的监控仪表板旨在成为实时调查运行手册,帮助调查人员从初步调查步骤(由表面拥有团队完成)进展到高级调查(由绩效团队完成)
初步调查
初步调查的步骤包括:
1.检查是否有任何其他表面同时开始回归(任何应用程序范围的回归调查都会升级到由性能团队进行的高级调查阶段)
2.确定回归的开始时间
3.检查与回归开始时间一致的部署和实验
确定回归的确切开始时间可以减少可能导致回归的内部更改。如果没有这条关键信息,导致回归的根本原因就会大大降低,因为提交列表、实验更改和其他类型的内部更改可能会变得非常多。
内部变化覆盖在 x 轴上,使我们能够识别部署、实验升级或其他类型的内部变化是否与回归的确切开始时间一致:
图 3:内部变化显示在 x 轴上,便于查看回归开始时发生了哪些变化
知道回归的开始时间通常足以确定根本原因。回归通常是由于 Web 部署或实验坡道引起的。如果是由于 Web 部署引起的,调查员会查看已部署的提交,以查找影响回归表面或通用组件的任何内容。通常,单个部署中的提交列表很短,因为我们会持续部署,每天会有 9-10 次部署。
有时,很难确定哪些内部更改导致了回归,尤其是当回归同时发生大量内部更改时(在代码冻结后或由于问题而阻止部署后,我们可能会进行异常大规模的部署)。在这种情况下,调查将升级到性能团队的值班人员,他们将进行高级调查。
高级调查
调查子指标并记录所有倒退的症状有助于缩小导致倒退的变化类型。我们监控的子指标包括自主开发的统计数据以及与性能相关的大多数标准化 Web API 的数据。
高级调查的步骤包括:
1.检查日志量和内容分布的变化
图 4:在高级调查中,我们首先仔细检查表面体积指标,以确定对数体积或内容分布的变化是否导致了回归
2. 确定回归在关键路径中的起始位置
图 5:下一步是检查表面时序指标,它可以显示回归在关键路径中的哪个位置开始
3.检查网络请求的变化
图 6:我们还检查网络请求中是否有任何变化,这些变化可能表明回归的来源
上图中显示的实时调查仪表板仅限于我们最有用的图表。根据上述步骤的结果,性能团队可能会检查内部性能团队仪表板中保存的其他指标,但大多数这些指标(例如内存使用情况、长任务、服务器中间件计时、页面大小等)更多地用于其他类型的性能分析。
去年,我们添加了两种新类型的指标,它们在多个迁移项目的回归调查中发挥了重要作用:
HTML 流计时
我们的大部分初始页面加载都是通过服务器端渲染完成的,HTML 在准备就绪后以块的形式流出。我们测量了从服务器生成关键 HTML 块(例如重要的脚本标记、预加载标记和 LCP 图像标记)的时间。这些时间有助于在 2023 年对服务器渲染过程进行更改时解决几个回归问题的根本原因。
例如,我们进行了一项测试网络流的实验,该实验显著改变了生成的 HTML 块数量以及 HTML 的流式传输方式。我们发现 LCP 图像的预加载链接标签比其他处理更早流式传输(这只是进行的分析示例,我们没有发送网络流处理):
图 7:实时指标计时了在测试的不同流处理中,流出包含英雄图像预加载标签的 HTML 块所需的时间
网络拥塞时间
我们对服务器和客户端进行了关键路径计时,并根据请求类型(图像、视频、XHR、css 和脚本)对网络请求进行了聚合(请求数量、大小和持续时间),但我们不了解网络请求何时开始和结束。
这促使我们测量网络拥塞时间。对于 Pinner 等待时间期间发生的所有请求,我们记录请求批次的开始和结束时间。例如,我们记录以下时间:
第一个脚本请求开始
25% 的剧本请求正在处理中
50% 的剧本请求正在处理中
…
25% 的脚本请求已完成
50% 的脚本请求已完成
ETC
这对于从根本上解决许多倒退问题非常有价值,其中包括:
LCP 图像的预加载请求延迟
脚本请求在 LCP 预加载请求完成之前开始,我们发现这与 LCP 图像加载时间更长有关
脚本请求提前完成,这可能会导致较长的编译任务启动
其他图片请求的开始或完成时间提前或推迟的变化
图 8:实时指标计时 25% 的脚本请求完成所需的时间与预加载图像请求完成所需的时间
这些指标以及其他实时子指标有助于调查棘手的实验回归问题,因为回归问题的根本原因无法从实验仪表板中显示的默认性能指标中看出。通过更新日志以标记实验和实验处理,我们可以比较任何实时子指标的实验组。
性能团队成立时,我们依靠每日汇总的性能指标来检测 Web 回归。调查这些回归非常困难,因为我们没有很多子指标,而且由于每天进行数百次内部更改,因此通常无法查明根本原因。我们将 PWT 和 CWV 作为顶级指标,同时添加可操作的补充指标(例如 HTML 流计时),有助于提高调查效率和成功率。此外,将我们的警报和调查流程转移到实时图表,并不断磨练哪些子指标最有用,大大提高了根本原因和解决回归的成功率。这些实时、真实的用户监控图表对于捕捉生产中发布的回归至关重要。在下一篇文章中,我们将深入探讨如何在回归完全发布到生产中之前捕捉它们,从而减少调查时间,进一步提高解决问题的可能性,并防止对用户的影响。
接下来,我们将重点介绍我们已部署的系统,用于主动检测和防止回归在生产中完全发布。
A/B 实验检查
通过内部收集性能指标,我们可以将这些日志传输到内部实验框架中。Pinterest 拥有出色的文化,将所有影响用户的重大更改都纳入 A/B 实验中,这使我们能够检测这些更改对性能的影响。下面,我们将描述如何检测和处理实验回归。
分级实验回归
如果实验在过去七天中连续五天或以上出现显著的性能退化,则会触发 Slack 警报和 Jira 工单,这些工单会传达有关退化的信息并跟踪修复进度。每个指标都会定义阈值来对退化进行分级,并且会为每个严重程度级别定义一组特定的后续步骤,涵盖实验升级、调查、缓解和权衡讨论(例如,对于高严重程度的退化,实验升级会被阻止)。
图 9:在 A/B 实验中检测到性能回归时自动生成的 Jira 票证示例
实验仪表板
对于每个实验,我们都会在核心指标的主仪表板中显示所有最重要的性能指标。这显示了每个 PWT 和核心 Web 重要指标的相对百分比增加(红色)或减少(蓝色):
图 10:A/B 实验主仪表板中显示的顶级性能指标
可以使用其他性能仪表板来帮助调查任何性能指标变动。这些仪表板为所选的顶线指标提供关键子指标,以便实验负责人可以调查回归的症状以及关键路径的变化情况。
图 11:附加性能仪表板可帮助调查所选性能指标的关键路径和回归症状
实时图表
当实验仪表板没有提供足够的细节时,我们可以通过在性能日志中标记实验名称来启用实时调试指标。这可以对上一篇关于实时监控的文章中提到的所有子指标(例如日志量、约束时间、注释时间、网络请求统计、网络拥塞时间和 HTML 流时间)进行控制和处理之间的详细比较。通常,这种级别的日志记录仅适用于平台级更改,因为对于这些更改,可能很难缩小回归的根本原因。
多年来,A/B 实验中的性能回归检测一直是我们主要的保护形式。仅在 2023 年,我们就在所有客户中检测并跟踪了超过 500 次实验回归。
Per-Diff JS 包大小检查
网络上的另一种主要保护形式是通过我们的 CI 管道在每次 PR 更新时运行 JS 包大小检查。从历史上看,我们已经看到过去超过 25% 的 PWT 回归是由于我们发送的 JS 数量增加而导致的。这些类型的回归很严重并不罕见(我们已经看到由于单个包大小回归导致 PWT P90 值增加 +800ms)。在 2021 年,我们为包大小检查启用了阻止警报,并将由于包大小增加而导致的生产回归数量减少到接近零。通常,一年内可以捕获并防止 3-5MB 的包大小回归。例如,在 2023 年,防止了 2.8MB 的包大小回归,这相当于在慢速 3G 网络上额外增加 60 秒的请求持续时间。
实施包大小检查就是在 webpack 构建期间生成和存储资产大小,该构建在我们的 CI 管道中针对主分支和任何 PR 分支运行。对于 PR 分支的任何 CI 构建,我们都会找到该分支的基本提交,从 s3 下载其资产大小文件,并将其用作基准,与分支提交的资产大小进行比较。
任何重大的包大小变化(无论是增加还是减少)都会在 PR 的评论中报告,以帮助开发人员了解他们的代码更改如何影响包大小。关键页面上的包大小增加还会触发 Slack 警报,发送给 PR 作者和表面拥有团队的警报渠道。表面拥有团队也被添加到 PR 的审阅者中。
图 12:针对关键回归的 JS 包大小检查的 PR 注释示例
这些警告消息链接到有关如何解决回归问题的指导。回归问题通常是由于新模块导入而引起的,通常可以延迟加载。找出回归问题的根源并修复它非常简单,几乎所有回归问题都可以由 PR 作者在无需帮助的情况下解决(自助服务性能万岁!)。对于根本原因不明显的情况,PR 作者将得到有关如何运行webpack-bundle-analyzer来调查大小增加的来源的指导:
图 13:用于调查实际发生的 bundle 大小回归的 webpack-bundle-analyzer 报告
与我们之前监控生产环境中的包大小的系统相比,该系统有了很大的改进,以前的系统仅限于少数几个关键的静态命名包。通过对每个不同的包大小进行检查,我们可以轻松检查我们知道的页面在构建时所需的所有包的大小,而 PR 作者能够自行检测和修复回归问题。这为性能团队节省了大量的工作,包括检测和根源性生产回归问题、与 PR 作者合作修复问题以及通过监控发布到生产环境中的修复来验证回归问题是否得到解决。它还可以防止回归问题影响用户,因为包大小增加的问题通常在 PR 合并之前得到解决。
Per-Diff 性能回归测试
虽然许多回归问题只有在向真实用户发布更改时才能检测到,但我们能够通过性能集成测试在合成环境中检测到某些回归问题。以前,我们对每个主分支提交都运行性能集成测试。与 JS 包大小检查类似,我们已经将这些测试迁移到每个 diff 运行(在 PR 合并之前),以防止回归问题影响到用户,提升自助服务性能,提高回归捕获率,并减少调查时间。我们正准备很快为 PR 作者启用回归警报,并希望在即将发表的文章中分享有关这些测试的实施细节和有效性的好消息。
总结
年复一年,Pinterest 的性能团队致力于优化、工具和回归消防相结合的工作。多年来,随着我们在更好的工具方面的投资,我们能够减少消防时间,而将更多时间用于优化。我们在性能工具方面的工作中获得了以下一些关键经验:
鉴于持续部署系统,具有细粒度时间间隔和丰富子指标的实时、真实用户监控对于导致生产回归的根本原因非常有价值
自动化、主动的系统(例如每次差异和 A/B 实验性能检查)非常有效,因为它们:
- 提供早期检测,通常可以防止回归完全影响生产并影响用户
- 隔离回归的可能根本原因
- 实现自助服务性能,最终节省工程资源
- 随着公司的发展,随着提交、实验和其他内部变化的速度增加,可以很好地扩展
如果警报可行且后续步骤有限,则更有可能及时调查和解决回归问题——回归警报应该清晰,并附带易于遵循的指导,可以在合理的时间内完成
这些系统在防止 Pinterest 的网络性能下降方面提供了极大的帮助,从而提高了我们的内部速度并为我们的用户提供了更好的体验。
FunTester 原创精华