1.3 捕获和计算
系统建模者说,我们可以通过建立系统的模型来改变范式,因为建模的过程会让我们跳出系统,把系统视为一个整体。
—Donella Meadows,《系统之美》
有了自己的定义后,就可以开始进行捕获和计算了。虽然将捕获的过程自动化非常好,但手工捕获也完全可以接受[10]。事实上,我每次引出这四个关键指标时,都会先从手工操作开始,而且相比于仅用作初始化指标基线,手工操作经常会持续被使用。你可以通过后续段落理解为什么手工捕获和计算是可行的。
捕获指标的工作既可能简单也可能复杂,这取决于流水线构造。无论如何,这四个关键指标都将使用四个检测点产生的四组数据来计算:成功变更的部署计数、每次变更流水线运行总时间、变更故障单的数量,以及变更故障单开启的时长。仅凭捕获的这些数据集还不足以得出指标,计算工作仍然是需要做的,所以让我们依次看一下指标的计算。
部署频率
这是一个频率,而不是一个计数,因此需要统计指定周期内成功部署的总数(我发现以天为周期即可)。如果有多个流水线,无论这些流水线是否是扇入型,你都可以对所有的流水线部署次数求和。
有了这些数据,每天进行记录和汇总(记住要包含那些没有发生部署的“零”计数),就很容易得到第一个关键指标。使用最新的每日数据或过去24小时的数据(以我的经验)产生的结果波动过大。最好是显示较长时间(比如最近31天)内的平均值。
变更前置时间
这是触发了流水线启动的变更所经历的时间。因为它可能会波动,所以不要只上报最新一次部署的数据。如果有多个(包括扇入型)流水线,这种波动将会大得多:由于阻塞,一些构建会比另一些构建运行得更快。我们期望用一些更稳定的信息来反映总体状态,而不是最新的异常值。因此,我通常会拿单独的前置时间测量值来计算一天中所有这些值的平均值,而报告中的数字则是过去31天内所有前置时间测量值的平均值[11]。
变更失败率
这是已解决的变更故障单的比例,具体来说是在同一时段内发生故障的部署数量占部署总数的比例。例如,如果一天内发生了36次变更部署,并且你在同一天解决了2次变更故障,则意味着当天的变更失败率为2/36,即5.555 555 56%。
为了得到报告汇总指标,向前推31天,计算这一时段内的变更失败率。这意味着需要将过去31天内恢复的故障数量相加,然后除以同一时段内的部署总数。
可以注意到,这里存在一个理解上的跳跃。我们在这里假设每个故障都是独立的,并且单个故障都是由单个部署引起的。为什么呢?因为根据我的经验,把故障关联到某一次构建上实在是太难了,而且在绝大多数事件中,这两种假设都成立,至少数据的失真在这里是可以接受的。当然,如果你能在这方面做得更好,那恭喜你!
细心的人会注意到,我们谈论的只是已解决的故障。为什么不包括那些尚未解决的故障呢?因为要确保四个关键指标的一致性,而且服务恢复时间只能考虑已解决的故障[12]。如果计算其中一个指标时不考虑未解决故障,那么也不必在计算另一个指标时考虑它。但别怕,我们仍然有未解决故障的数据,我们不会隐藏这些数据,正如你将在接下来的章节中看到的那样。
服务恢复时间
这是变更故障单从开启到关闭所经过的时间。Accelerate的作者称之为平均服务恢复时间,尽管在早期的State of DevOps报告中,它只被称为恢复时间,并且在Google的Four Keys项目的MET-RICS.md(https://oreil.ly/VlSgn)文件中被称为中位数恢复时间。平均值和中位数我都用过;前者对异常值更敏感,有时候这正是你在调研过程中想要看到的。
平均值和中位数都很容易从变更故障单的解决时长数据中计算出来。无论采用哪种方式,我们都希望在一定的数据范围内选择输入值。我通常会选择最近120天的数据。把所有落在该时间段内的故障恢复时长都拿出来,计算平均值,并将其报告为服务恢复时间指标。
这里存在另一个潜在的理解上的跳跃:当手动创建变更故障单时,有可能因为创建时间晚于故障被发现的时间而导致数字产生偏斜。就算人们的意图是好的,偏斜仍会发生。不过,即便这样,我们也能得到足够引起关注的数据,并推动改进。
无论如何获取这些计算所需的数据,都要确保这些数据是公开的。首先,鼓励开发团队仔细阅读这四个关键指标。你的努力不应该留有任何秘密。
其次,提供所有原始数据和计算结果,以及计算出来的关键指标。这一点在以后会变得很重要。
再次,在提供数据本身的同时,确保应用于每个指标的定义,以及处理这些定义的方式也一并提供。这种透明度将有助于团队加深理解并提高参与度[13]。
最后,应当关注这些指标是否可被访问(包括数据访问、计算和可视化),因为如果不将四个关键指标与所有人分享,就会错过发挥它们最大优势的机会。