衡量您的 SLO

Last reviewed 2024-03-29 UTC

Google Cloud 架构框架中的这篇文档在之前服务等级目标 (SLO) 的讨论基础上,探讨了有关常见服务工作负载的衡量内容以及衡量方法。本文档以服务等级目标组成部分中所述的概念为基础。

确定要衡量的内容

无论您的网域如何,许多服务都具有相同的功能,可以使用通用 SLO。本部分讨论了不同服务类型的通用 SLO,并详细介绍了适用于每个 SLO 的 SLI。

以下各小节分别介绍了一种特定的服务类型,并提供各服务的简短说明。然后,在每个服务类型下列出了可能的 SLI、指标的定义以及与 SLI 相关的其他信息。

请求驱动的服务

此服务类型会接收来自客户端(用户或其他服务)的请求,执行一些计算,可能将网络请求发送到后端,然后向客户端返回一个响应。

可用性作为 SLI

可用性是指成功处理的有效请求所占的比例。以下列表介绍了将可用性用作 SLI 时需要考虑的事项:

  • 作为服务所有者,您可以决定什么是有效请求。常见的定义包括“长度非零”或“遵循客户端-服务器协议”。衡量有效性的一种方法是审核 HTTP(或 RPC)响应代码。例如,HTTP 5xx 代码是与服务器相关的错误,计入 SLO;而 4xx 代码是客户端错误,不计入 SLO。
  • 必须检查您的服务返回的每个响应代码,以确保应用正确、一致地使用这些代码。代码能否准确反映用户服务体验?例如,当用户尝试订购缺货的商品时,电子商务网站如何响应?请求是否失败并返回错误消息?网站是否推荐类似产品?错误代码必须与用户预期相关联。
  • 开发者可能会无意中误用错误。在前文提到的缺货场景中,开发者可能会错误地返回错误。不过,系统运行正常,没有出现错误。即使用户无法购买相应商品,代码也需要返回成功结果。此服务的所有者需要知道库存较低,但从客户的角度来看,无法进行销售不是错误,不应计入 SLO。
  • 一个更复杂的服务示例是处理异步请求或为客户提供长时间运行的进程。虽然您可以通过其他方式公开可用性,但我们建议将可用性表示为成功的有效请求所占的比例。可用性也可以定义为客户的工作负载正常运行的分钟数(有时称为“良好时间”方法)。
  • 假设有一项提供虚拟机的服务。您可以根据初始请求后用户可以访问虚拟机的分钟数来衡量可用性。

延迟时间作为 SLI

延迟时间(或速度)是指处理速度超过阈值的有效请求所占的比例。因此,延迟时间表示服务速度,可通过计算给定请求类型的开始时间和停止时间之差来衡量。请记住,这是用户对延迟时间的感知,服务所有者通常太过于精确地测量此值。实际上,用户无法区分 100 毫秒 (ms) 和 300 毫秒的刷新时间,甚至可能照常接受 300 毫秒到 1000 毫秒之间的响应时间。如需了解详情,请参阅 Rail 模型

开发以活动为中心的指标,以用户为本。以下是此类指标的一些示例:

  • 交互式:用户在点击元素后等待 1000 毫秒才能看到结果。
  • 写入:对底层分布式系统的更改需要 1500 毫秒。尽管这个时间长度有点慢,但用户还是能够接受。我们建议您在指标中明确区分写入和读取。
  • 后台:完成用户不可见的操作(例如定期刷新数据或其他异步请求)所需的时间不会超过 5000 毫秒。

延迟时间通常以分布的形式进行衡量,如选择 SLI 中所述。在给定分布的情况下,您可以测量各种百分位数。例如,您可以测量比历史第 99 个百分位慢的请求数。快于此阈值的事件被视为良好;较慢的请求则视为不太好。您可以根据产品要求设置此阈值。您甚至可以设置多个延迟时间 SLO,例如典型延迟时间与尾延迟时间。

请勿仅使用平均(或中位数)延迟时间作为 SLI。如果延迟时间中位数太慢,则表示一半的用户已经感到不满。此外,在您发现问题之前,您的服务可能会面临数天的延迟。因此,请为尾延迟时间(第 95 百分位)和延迟时间中位数(第 50 百分位)定义 SLO。

在 ACM 文章重要指标中,Benjamin Treynor Sloss 写下以下内容:

  • “一个很好的实际经验法则…第 99 百分位延迟不应超过延迟时间中位数的三到五倍。”
  • “我们发现服务的第 50、95 和 99 百分位延迟时间度量值都是单独有价值的,理想情况下,我们将围绕这些值设置 SLO。”

根据历史百分位数确定延迟时间阈值,然后测量每个存储桶中有多少请求。这种方法是个值得遵循的好模式。

质量作为 SLI

质量是指已处理且服务没有降级的有效请求所占的比例。例如,对于设计为正常失败的复杂服务,质量是很有帮助的 SLI。为了说明这一点,假设有一个网页从一个数据存储区加载其主要内容,并从 100 个其他服务和数据存储区加载可选资产。如果某个可选元素已中断运行或运行速度太慢,那么仍会呈现网页但不会包含该可选元素。在此场景中,您可以使用 SLI 执行以下操作:

  • 通过测量收到降级响应的请求数(即,缺少至少一个后端服务回复的响应),可以报告不良请求的比例。
  • 您可以跟踪缺少一个后端或多个后端回复的响应数量。

数据处理服务

这些服务使用来自输入的数据、处理该数据并生成输出。中间步骤的服务性能并没有最终结果那么重要。最强大的 SLI 是新鲜度、覆盖率、正确性和吞吐量。延迟时间和可用性不那么有用。

新鲜度作为 SLI

新鲜度是指更新时间超过阈值的有效数据的比例。以下列表提供了一些将新鲜度用作 SLI 的示例:

  • 在批处理系统中,按照为给定输出成功运行一项处理后所经过的时间来衡量新鲜度。
  • 实时处理系统或更复杂的系统中,新鲜度会跟踪在流水线中处理的最新记录的存在时间。
  • 在一款实时生成地图图块的在线游戏中,用户可能不会注意到创建地图图块的速度有多快,但他们可能会注意到地图数据丢失或不是最新。在这种情况下,新鲜度会跟踪缺失或过时的数据。
  • 假设某项服务会读取跟踪系统的记录,从而为电子商务网站生成消息“X 件商品有货”,则可以将新鲜度 SLI 定义为使用了最近(最后一分钟内)刷新的库存信息的请求所占的百分比。
  • 您还可以使用传递非刷新数据的指标来更新质量 SLI

覆盖率作为 SLI

覆盖率是指已成功处理的有效数据的比例。

如需定义覆盖率,请按以下步骤操作:

  1. 确定是将输入作为有效项接受还是跳过该输入。例如,如果输入记录损坏或长度为零,无法处理,您可以考虑将该记录视为无效指标。
  2. 计算有效记录数。此数量可以通过简单的 *count() *方法完成,它可表示您的总记录数。
  3. 最后,计算已成功处理的记录数,并将该数量与有效记录总数进行比较。此值是您的覆盖率 SLI。

正确性作为 SLI

正确性是指生成正确输出的有效数据所占的比例。 将正确性用作 SLI 时,请考虑以下几点:

  • 在某些情况下,您可以通过各种方法确定输出的正确性,以验证输出的处理情况。例如,旋转图片或为之着色的系统绝不应产生零字节图片,或长度或宽度为零的图片。请务必将此验证逻辑与处理逻辑本身区分开来。
  • 测量正确性 SLI 的一种方法是使用已知良好的测试输入数据。这种类型的数据会生成已知正确的输出。请注意,输入数据必须代表用户数据。
  • 在其他情况下,可能会对输出使用数学或逻辑检查,如前面旋转图片的示例所示。
  • 最后,假设有一个结算系统,它通过检查交易前的余额与交易后的余额之间的差值来确定交易是否有效。 如果此值与交易本身的值相符,则是有效交易。

吞吐量作为 SLI

吞吐量是指数据处理速率快于阈值的时间比例。将吞吐量用作 SLI 时,需要考虑以下几点:

  • 在数据处理系统中,吞吐量通常比对给定操作的单一延迟度量更能代表用户的满意度。如果每个输入的大小变化很大,则比较每个元素完成的时间可能就没有意义了(如果所有作业都以可接受的速度进行)。
  • “每秒字节数”是测量处理数据所需工作量(无论数据集的大小如何)的常用方法。但是,任何与处理成本大致成线性关系的指标都是可行的。
  • 根据预期吞吐率对数据处理系统进行分区,这可能是值得的。或实现服务质量系统,以确保处理高优先级输入并对低优先级输入进行排队。无论哪种方式,按照本节所定义的方式测量吞吐量都可以帮助您确定系统是否在 SLO 范围内工作。

计划执行服务

对于需要按固定间隔执行操作的服务(例如 Kubernetes cron 作业),您可以测量“偏差”和“执行时长”。以下是计划的 Kubernetes cron 作业示例:

  apiVersion: batch/v1beta1
  kind: CronJob
  metadata:
  name: hello
  spec:
schedule: "0 * * * *"

偏差作为 SLI

偏差是指在预计开始时间的可接受时段内开始的执行所占的比例。使用偏差时,请考虑以下事项:

  • “偏差”衡量作业的计划开始时间与实际开始时间之间的时间差。假设还是使用前面的 Kubernetes cron 作业示例。如果设置为从每小时的零分钟开始,而实际在每个小时的第三分钟开始,则偏差为三分钟。如果作业提前运行,则偏差为负。
  • 您可以用一段时间的分布情况来衡量偏差,并使用相应的可接受范围来定义良好的偏差。若要确定 SLI,请比较良好范围内的运行次数。

执行时长作为 SLI

“执行时长”是指在可接受的时段内完成的执行所占的比例。下面介绍了与使用执行时长相关的重要概念:

  • “执行时长”是指完成作业所需的时间。对于给定执行,常见的故障模式是实际时长超过计划时长。
  • 一个有趣的案例是,将此 SLI 应用于永无止境的作业。由于这些作业没有完成,因此请记录给定作业花费的时间,而不是等待作业完成。此方法提供了工作完成时间(即使在最坏情况下)的准确分布。
  • 与偏差一样,您可以将执行时长作为分布情况来跟踪,并为良好事件定义可接受的上限和下限。

其他系统类型的指标

许多其他工作负载都有自己的指标,可用于生成 SLI 和 SLO。请参考以下示例:

  • 存储系统:耐用性、吞吐量、第一字节时间 (Time to First Byte)、blob 可用性
  • 媒体/视频:客户端播放连续性、开始播放的时间、转码图执行完整性。
  • 游戏:匹配活跃玩家的时间、生成地图的时间。

确定如何衡量

上一部分介绍了您要衡量的内容。在确定要衡量的内容后,您可以决定如何进行衡量。您可以通过多种方式收集 SLI 指标。下面的部分将阐述各种测量方法,提供各方法的简要说明,列出各方法的优缺点,并指出各方法的相应实现工具。

服务器端日志记录

服务器端日志记录方法涉及以下过程:处理请求或已处理数据的服务器端日志。

服务器端日志记录 详情
优点
  • 重新处理现有日志以回填历史 SLI 记录。
  • 使用跨服务会话标识符跨多个服务重建复杂的用户历程。
缺点
  • 系统不会记录未到达服务器的请求。
  • 导致服务器崩溃的请求可能无法被记录。
  • 处理日志的时间长度可能会导致过时的 SLI,这可能是因为操作响应的数据不足。
  • 写入代码以处理日志可能是一项容易出错、耗时的任务。
实现方法和工具

应用服务器指标

应用服务器指标方法涉及以下过程:从处理用户请求或处理其数据的代码导出 SLI 指标。

应用服务器指标 详情
优点
  • 向代码中添加新指标通常既快捷又费用不高。
缺点
  • 系统不会记录未到达应用服务器的请求。
  • 多服务请求可能难以跟踪。
实现方法和工具

前端基础设施指标

前端基础设施指标方法使用负载均衡基础设施(例如 Google Cloud 中的全球第 7 层负载均衡器)中的指标。

前端基础设施指标 详情
优点
  • 指标和历史数据通常都已存在,因此减少了工程的入门工作量。
  • 测量是在最靠近客户的位置进行,但仍在服务基础设施内。
缺点
  • 不适用于数据处理 SLI。
  • 只能大致估算多请求用户历程。
实现方法和工具

合成客户端或数据

合成客户端或数据方法会使用定期发送虚构请求并验证响应的客户端。

合成客户端或数据 详情
优点
  • 衡量多请求用户历程的所有步骤。
  • 从基础设施外部发送请求会捕获 SLI 中更多的整体请求路径。
缺点
  • 借助合成请求大致估算用户体验,可能会有误导性(假正例或假负例)。
  • 覆盖所有极端情况是困难的,可以转移到集成测试中。
  • 可靠性高的目标需要频繁探测才能进行准确测量。
  • 探测流量会消除真实流量。
实现方法和工具

客户端插桩

客户端插桩方法涉及以下过程:向用户与之交互的客户端添加可观察性功能,并将事件记录回跟踪 SLI 的服务基础设施。

客户端插桩 详情
优点
  • 提供最准确的用户体验衡量。
  • 可以量化第三方(例如 CDN 或付款服务机构)的可靠性。
缺点
  • 客户端日志提取和处理延迟使这些 SLI 不适合触发操作响应。
  • SLI 衡量指标包含许多可能不受直接控制的高度可变的因素。
  • 将插桩构建到客户端中可能涉及大量的工程工作。
实现方法和工具

选择测量方法

确定要衡量的 SLO 内容衡量方式之后,下一步是选择与客户的服务体验密切相关的衡量方法,并且需要投入一定的精力。为了实现此理想情况,您可能需要组合使用上表中的方法。下面是建议的方法,按工作量增加的顺序列出,您可以慢慢实现:

  • 使用应用服务器导出和基础设施指标。通常,您可以立即访问这些指标,并且它们会快速提供值。一些 APM 工具包含内置 SLO 工具。
  • 使用客户端插桩。由于旧式系统通常缺少内置的最终用户客户端插桩,因此设置插桩可能需要大量投入。但是,如果您使用能提供客户端插桩的 APM 套件或前端框架,则可以快速了解客户的满意度。
  • 使用日志处理。如果您无法实现服务器导出或客户端插桩(前面的项目符号项),但存在日志,则日志处理可能是最佳方法。另一种方法是合并导出和日志处理。将导出用作某些 SLI(例如即时可用性)的直接来源,并将日志处理用于长期信号(例如 SLO 和提醒指南中讨论的慢速消耗提醒)。
  • 实现合成测试。在基本了解客户如何使用您的服务后,便可以测试服务。例如,您可以用已知的良好数据为测试账号播种,并对其进行查询。此方法有助于突出显示不容易观察到的故障模式,例如低流量服务。

后续步骤