2021年4月20日

应用程序监控最佳实践

监控对于确保应用程序的可靠运行至关重要,也是 DevOps 运动的重要实践。了解有关监控在开发工作流程中的作用以及监控应用程序的最佳实践的更多信息。

Application Monitoring Best Practices

简介

作为开发人员,您可能负责开发功能并确保它们可靠运行。但是,为什么监控如此重要?监控应用程序的最佳实践是什么?

在本文中,您将了解

注意:本文交替使用术语后端、应用程序和服务。它们都指同一件事。

什么是监控?

监控是收集、处理、聚合和可视化有关系统的实时定量数据的实践。在应用程序的上下文中,测量的数据可能包括请求计数、错误计数、请求延迟、数据库查询延迟和资源利用率。

例如,假设您正在为应用程序开发新的搜索功能,并引入一个新的 API 端点来查询。您可能对测量服务此类搜索请求所花费的时间感兴趣,并跟踪当该端点的并发负载增加时它的性能如何。您可能会发现,当用户搜索特定字段时,由于缺少索引,延迟会增加。监控可以帮助您检测此类异常或性能瓶颈。

为什么监控很重要?

监控之所以重要有几个原因 – 理解这些原因有助于您在实施和工具选择方面做出选择。从高层次来看,监控可以帮助您确保应用程序的可靠运行。

对原因进行更深入的探讨包括

  • 警报:当您的应用程序发生故障时,您通常希望尽快修复它。通过您正在监控的有关系统的实时数据可以实现警报。当监控的指标值超过阈值时,您可以定义警报,指示需要开发人员干预的错误。反过来,您能够迅速响应并减少用户遇到的停机时间和潜在的收入损失。
  • 调试:当您的应用程序发生故障时,您不希望在黑暗中摸索。监控可帮助您找到故障的根本原因,并帮助您解决问题。
  • 分析长期趋势:能够查看您的应用程序随着活跃用户增长随时间推移的资源利用程度,可以帮助进行容量规划和扩展工作。此外,监控还可以深入了解新功能和用户采用之间的关系。

Web 应用程序往往会随着时间的推移而变得越来越复杂。即使是看似简单的应用程序,一旦部署后,在考虑它们在负载下的运行方式时,也可能难以理解。此外,抽象层和外部库的使用会模糊应用程序的底层机制和故障模式。监控为您提供了对应用程序的运行状况和运行情况的 X 射线般的视觉。

监控是面向客户的 SaaS 公司不可或缺的工具。SaaS 公司通常会在服务级别协议 (SLA) 中使用正常运行时间期望来保证其服务的可靠性。服务级别协议定义了客户应从 SaaS 服务提供商处获得的期望,并充当法律文件。例如,许多云服务保证 99.99% 的正常运行时间,这相当于每年可接受的停机时间为 52.60 分钟。监控本质上允许您降低风险并跟踪停机时间,同时使其尽可能低(使用警报)。

监控如何与敏捷开发方法相关?

如今,工程团队越来越多地采用敏捷开发方法,专注于频繁交付增量变更,并依赖自动化工具来实现变更的持续交付。

敏捷开发方法使开发团队能够通过拥抱变化并频繁部署来缩短上市时间。

这通常是通过自动化开发工作流程的可重复方面,并创建一个实时反馈循环来实现的,该循环使工程师能够分析其更改对生产系统的影响。在这样的环境中,监控是创建实时反馈循环的重要工具之一。

监控如何融入您的开发工作流程?

了解监控如何融入开发工作流程的一个有用的方法是查看 DevOps 无限循环。DevOps 理念将开发软件与操作软件更紧密地结合在一起——这两个学科传统上被视为由不同团队处理的单独问题。

DevOps infinity loop

这两个学科的合并扩大了工程团队的责任,并使他们能够拥有从开发到操作生产部署的整个开发生命周期。DevOps 原则“您构建它,您运行它”抓住了这个想法的精髓。

实际上,监控是三个阶段中需要解决的问题

  • 规划
  • 开发
  • 部署更改后的操作阶段

在规划阶段,您将确定一些从服务级别协议 (SLA) 派生的初始服务级别指标 (SLI)。SLI 是关于您的应用程序的可衡量指标,指示您是否符合 SLA。例如,如果您的 SLA 声明 99.9% 的正常运行时间,则相应的 SLI 将是您服务的每月或每年停机时间。

请注意,设置 SLI 目标虽然通常源自 SLA,但也受到您的应用程序架构以及您决定测量和跟踪的指标的影响。

在开发阶段,应用程序代码会使用监控逻辑进行检测,该逻辑会公开诸如应用程序的内部性能、负载和错误计数等指标。例如,在构建公开 GraphQL API 的应用程序时,您可以检测代码以收集诸如请求计数(按 HTTP 响应代码分组)和请求延迟等指标。在每次请求时,检测代码都会增加请求计数并跟踪请求延迟。

在您的应用程序代码经过测试并部署到生产环境后,您可以使用监控工具(或服务)来收集、存储和可视化应用程序中检测公开的信息。通常,此类工具还带有警报功能,您可以对其进行配置,以便在发生需要开发人员干预的故障时发送警报。

可视化收集的指标使您可以实时了解应用程序的运行状况和内部状况。例如,以上面的示例为基础,您可能会创建一个带有图表的仪表板来可视化每分钟的请求、请求延迟和系统资源利用率(CPU、磁盘、网络 I/O 和内存)。此外,您还可以为请求延迟高于某个阈值的情况设置警报。

总之,您应该在整个开发工作流程中考虑监控。

要监控什么?

在设置监控时,您希望监控帮助您回答两个问题:哪里出了问题以及为什么。换句话说,您希望监控能指出症状及其潜在原因。

例如,如果您只监控 HTTP 响应代码,您将能够在应用程序出现问题时发出警报。但是,这种监控无法帮助您回答请求失败的原因。

在决定监控什么时,需要考虑的另一个方面是应用程序的更广泛目标及其如何适应业务目标。例如,您可能从产品或分析团队了解到,用户流失可能与响应缓慢有关。对于企业来说,这可能意味着收入损失。在这种情况下,您需要设置服务水平目标 (SLO),该目标定义了您对应用程序的期望,例如,在 500 毫秒内处理请求,并定义相应的监控指标。

这就是 SLO 和 SLI 如何结合的地方。虽然 SLO 定义了您的目标,但 SLI 是您希望在应用程序中监控的相应测量值。

理想情况下,您收集的监控数据应该是可操作的。如果您收集了过多的指标,您的信噪比将会降低,从而使调试生产问题更加困难。如果您无法使用某个指标来定义驱动警报或提供系统整体运行状况的鸟瞰图,请考虑将其删除。

黑盒监控和白盒监控

监控有两种类型:黑盒监控和白盒监控,两者在您的监控设置中都起着至关重要的作用。

黑盒监控是指测量用户观察到的外部可见行为。另一种看待它的方式是,黑盒监控探测服务的外部特征,并帮助回答诸如以下问题:服务响应客户端请求的速度有多快?它是否返回了正确的数据或响应代码?

虽然黑盒监控有助于了解应用程序的状态,但它并不能揭示问题的内部原因。

白盒监控关注应用程序的内部结构,包括直接从您的应用程序代码公开的指标。白盒指标应以可以识别问题原因的方式确定。示例包括

  • 错误和异常
  • 请求速率
  • 数据库查询延迟
  • 待处理数据库查询的计数
  • 与其他服务通信的延迟。

部署到云端的应用程序通常涉及与其他数据源和服务进行通信,尤其是在微服务架构中。考虑到此类系统必然会出现的各种潜在故障模式,您还应该考虑监控允许您评估这些故障模式对服务的影响的指标。如果您拥有其他服务,也请考虑监控它们,因为一个服务中的问题可能会导致另一个服务出现症状。

有几种方法可以帮助您选择要监控的内容。请继续阅读以了解更多信息。

RED 方法 – 速率、错误、持续时间

RED 方法定义了您应该在应用程序/服务中测量的三个关键指标

  • 请求速率:您的应用程序每秒处理的请求数。
  • 请求错误:每秒失败的请求数。
  • 请求持续时间:每个请求所花费的时间量(即持续时间)的分布情况。

请注意,这些指标指的是客户端/用户请求。在使用数据库的应用程序中,您也可以将这些指标应用于数据库查询,并测量数据库查询计数、错误和持续时间。

这三个指标可以为您提供有关服务负载、错误数量以及负载和延迟之间关系的概述。

总之,RED 方法非常适用于请求驱动的应用程序,例如 API 后端。RED 方法深受 Google 的四个黄金信号方法的影响,我们将在下面介绍。

四个黄金信号

四个黄金信号方法定义了您可以在应用程序中测量的以下四个指标类别

  • 延迟:处理请求所花费的时间,按请求是否成功进行分类。
  • 流量:衡量应用程序的负载,例如,每秒请求数。
  • 错误:失败请求的比率。
  • 饱和度:衡量应用程序的负载程度。除非您通过运行负载测试知道应用程序可以处理的负载上限,否则这可能很难衡量。因此,使用资源利用率的代理度量,例如,CPU 负载和内存消耗。

此方法由 Google 的站点可靠性工程团队构思,并通过站点可靠性工程书籍推广开来。

如何监控?

前面的章节奠定了监控的理论基础。在本节中,您将了解用于监控的工具和平台。

用于监控的工具和平台格局正在迅速扩展。此外,还出现了新的术语,这可能会让人感到困惑,难以理解并比较解决方案。因此,考虑指标的五个阶段会很有帮助

  1. 检测:以监控工具可以消化的格式在应用程序代码中公开内部服务指标。
  2. 指标收集:监控工具收集指标或将指标发送给监控工具的机制。
  3. 指标存储和处理:存储和处理指标的方式,以便为您提供随时间的见解。
  4. 指标可视化:以人类可读的方式直观地表示指标的机制;通常作为仪表板的一部分
  5. 警报:一种机制,当指标数据检测到异常或故障并需要您的干预时,会通知您。

这五个阶段的实现很大程度上取决于您选择的监控工具。监控工具可以分为两类:自托管或托管,并且有几个需要考虑的权衡因素。

自托管监控工具会带来需要管理的另一个基础设施组件的开销。由于它们扮演着如此重要的角色,监控工具的故障可能会导致无人注意的停机时间。此外,您的架构可能不够复杂,无法证明自托管的合理性。另一方面,监控数据可能很敏感,并且根据安全策略,使用第三方托管服务可能不是一个选择。

旁注: OpenTelemetry 致力于创建一个单一的开源标准和一组技术,用于从您的应用程序和基础设施中捕获和导出指标、跟踪和日志,以进行分析以了解软件的性能和行为。该标准于 2021 年 2 月达到了 v1.0 版本,因此可能会有一些不完善之处。但总的来说,它可以简化检测和收集指标所需的开发人员工作流程,并提供更多的平台/工具互操作性。

现在,让我们看看一些工具和服务以及它们与这五个阶段的关系。

Prometheus、Grafana 和 Alert manager

Prometheus 是一个开源的监控系统和警报工具包。它内部有一个时序数据库,用于存储指标。它还具有用于查询和可视化指标的查询语言。

Grafana 是一个开源可视化工具,支持包括 Prometheus 在内的许多数据源。使用 Grafana,您可以创建仪表板来可视化指标。

通常,Prometheus 是自托管的;但是,近年来,出现了托管的 Prometheus 服务,从而减少了运行它相关的开销。

Prometheus 鼓励使用拉取模型,即 Prometheus 通过对应用程序中检测代码公开的指标端点进行 HTTP 调用来拉取指标。

Prometheus 生态系统由多个组件组成

  • Prometheus 服务器,用于抓取和存储时序数据
  • 用于检测应用程序代码的客户端库
  • 用于处理警报的 Prometheus Alertmanager

实际上,使用 Prometheus 进行监控如下所示

  1. 使用适用于多种流行语言(包括 Go、Node.js 等)的客户端库检测您的应用程序。客户端库为您提供三种指标类型:计数器、仪表和直方图,您根据要测量的内容在代码中实例化它们。例如,您可能会添加一个请求计数器,并在每次收到请求时递增它。最后一步是创建一个指标 HTTP 端点,Prometheus 会定期抓取该端点。
  2. 部署 Prometheus 服务器并配置要抓取的检测服务。
  3. 部署 Prometheus Alertmanager 并配置警报。
  4. 部署 Grafana,添加 Prometheus 作为数据源,并设置仪表板以可视化您正在跟踪的指标。

Prometheus 定期向已配置服务的指标端点发出 HTTP 请求,并将信息存储在其时序数据库中。每次拉取指标时,它都会根据警报规则检查指标。如果满足警报条件,Prometheus 会触发警报。

Prometheus 非常强大,非常适合微服务架构。但是,它需要运行多个基础设施组件(Prometheus、Alertmanager、Grafana),如果您有一个相对简单的架构,可能会有点过分。

Sentry

Sentry 是一个开源应用程序监控平台,提供错误跟踪、监控和警报功能。Sentry 的独特之处在于它允许您同时监控前端和后端,从而深入了解整个堆栈。此外,它还可以帮助您修复生产错误并优化应用程序的性能。

Sentry 采用整体性的监控方法,其前提是错误通常始于代码变更。在实践中,Sentry 收集关于应用程序内部的数据,例如未处理的错误和性能指标,以及关于发布的元数据,即部署信息。这种方法比典型的监控系统更广泛,使您可以将错误和性能下降与特定的代码更改联系起来。

与 Prometheus 相比,Sentry 使用推送模型将错误和指标推送到 Sentry 平台。

实际上,使用 Sentry 托管平台进行监控的过程如下:

  1. 创建一个 Sentry 账户
  2. 使用 Sentry 的特定语言 SDK 来检测您的后端。一旦您初始化 SDK,它就会发送未处理的错误并收集您定义的关于应用程序的指标。
  3. 设置警报,以便在发生错误指标超出阈值时通知您。

Sentry 支持两种类型的警报:指标警报和问题警报。当给定指标超过您定义的阈值时,会触发指标警报。每当 Sentry 在应用程序中捕获到未捕获的错误时,就会触发问题警报。

您可以配置警报,通过电子邮件或支持的集成之一通知您。

New Relic

New Relic 是一个可观测性平台,它提供用于分析和排除整个软件堆栈中问题的特性和工具。

注意: 可观测性监控之间的界限通常是模糊的。由于两者密切相关,因此有必要澄清两者之间的区别。可观测性可以被看作是监控的超集,它除了包括监控之外,还包括跟踪和日志。虽然监控用于报告系统的整体健康状况,但可观测性提供对系统行为的高度精细的洞察力以及丰富的上下文信息,非常适合用于调试。

New Relic 的可观测性功能不仅仅局限于监控,还包括四种基本的可观测性数据类型

  • 指标:关于您的应用程序的数值测量,如本文前面所述。
  • 事件:关于您的应用程序的特定领域事件。例如,在电子商务应用程序中,您可以在用户下订单时发出 OrderConfirmed 事件。
  • 日志:您的应用程序发出的日志。
  • 跟踪:微服务生态系统中不同组件之间事件因果链的数据。

实际上,使用 New Relic 进行监控的过程如下:

  1. 创建一个 New Relic 账户
  2. 使用 New Relic 代理检测您的应用程序,该代理将指标和跟踪发送到 New Relic。
  3. 在 New Relic 上定义警报并配置仪表板。

New Relic 支持许多不同的集成,允许您从各种编程语言、平台和框架收集数据,如果您的架构复杂,并且由以不同语言编写的组件和服务组成,则 New Relic 会很有吸引力。

监控与分布式跟踪有何关系?

虽然本文的重点是监控,但值得一提的是分布式跟踪,因为它经常出现在监控和可观测性的上下文中。

在微服务架构中,请求跨多个服务是很常见的。每个服务通过执行一个或多个操作来处理请求,例如数据库查询、将事件发布到消息队列以及更新缓存。使用此类架构的开发人员可能会很快忽略全局系统行为,从而难以排除问题。

分布式跟踪是一种用于分析和监控应用程序的方法,特别是那些使用微服务架构构建的应用程序。分布式跟踪有助于查明故障发生的位置以及导致性能不佳的原因。

它通过为外部请求分配一个唯一的外部请求 ID 来实现,该 ID 会传递给参与处理请求的所有服务。所有参与的服务都会记录关于请求和执行的操作的信息(开始时间、结束时间)。记录的信息由跟踪工具收集,该工具会可视化此信息。

分布式跟踪以一种微妙但根本的区别补充了监控。虽然监控有助于确保特定服务的可靠性,但分布式跟踪可以帮助您理解和调试服务之间的关系。换句话说,跟踪适用于调试微服务架构,其中服务之间的关系可能导致瓶颈和错误。

结论

在本文中,您了解了监控应用程序的最佳实践。首先从基础知识开始,然后深入研究监控如何融入开发工作流程,监控什么以及帮助您实现此目的的工具。

选择监控工具或平台可能很棘手。因此,理解监控背后的原理至关重要,因为它使您能够做出更明智的选择。

单靠监控不会使您的应用程序免受故障的影响。相反,它将为您提供生产中系统行为和性能的全景视图,使您能够看到任何故障的影响,并指导您确定根本原因。

总而言之,监控是软件开发的关键方面,也是在确保应用程序的可靠性和性能的同时实现快速开发的一项基本技能。

不要错过下一篇文章!

注册 Prisma 新闻简报