带你读《Prometheus监控实战》之一:监控简介

云计算与虚拟化技术丛书
点击查看第二章
点击查看第三章
Prometheus监控实战
Monitoring with Prometheus
带你读《Prometheus监控实战》之一:监控简介
[澳] 詹姆斯·特恩布尔(James Turnbull) 著
史天 张媛 肖力 译
第1章

监 控 简 介

本书的核心是Prometheus,一个开源的监控系统,它从应用程序中实时获取时间序列数据,然后通过功能强大的规则引擎,帮助你识别监控环境所需的信息。在下一章中,我们将介绍Prometheus及其架构和组件。本书将指导你使用Prometheus来构建监控系统,重点将放在动态云环境、Kubernetes环境和容器环境的监控。同时,我们还将研究如何从应用程序获取数据并将这些数据用于警报和可视化。
与此同时,这也是一本关于监控的书,所以在介绍Prometheus之前,本章将带你了解一些监控的基础知识。我们会循序渐进地介绍什么是监控,以及通用的监控方法,并会解释一些将在本书后面章节提到的术语和概念。

1.1 什么是监控

从技术角度来看,监控(monitoring)是衡量和管理技术系统的工具和流程。但监控远不止于此,监控将系统和应用程序生成的指标转换为对应的业务价值。你的监控系统会将这些指标转换为衡量用户体验的依据,该依据为业务提供反馈,以确保为客户提供了所需的产品。同时该依据还提供了对技术的反馈,指出哪些组件不起作用或者导致服务质量下降。
实际上,监控系统有以下两个“客户”:

  • 技术
  • 业务

1.1.1 技术作为客户

监控系统的第一个客户是技术,这是你、你的团队以及其他管理和维护技术环境的同事(可能被称为运维工程师、DevOps或是SRE)需要面对的。你可以通过监控来了解技术环境状况,还可以帮助检测、诊断和解决技术环境中的故障和问题(尤其是在影响用户之前)。监控提供了大量的数据,帮助洞察关键的产品和技术决策,并衡量这些项目是否成功。监控也是产品管理生命周期以及与内部客户关系的基础,有助于验证项目资金是否得到充分利用。如果没有监控,那么最好的情况是没有问题发生,最糟糕的情况则是问题发生了但没有被发现。
注意:
Google SRE手册中有一个很棒的图表,显示了监控是构建和管理应用程序层次结构的基础。

1.1.2 业务作为客户

业务是监控系统的第二个客户。监控系统是为了支持业务,并确保业务持续开展。监控可以提供报告,使企业能够进行良好的产品和技术投资,还有助于企业衡量技术带来的价值。

1.2 监控基础知识

监控是管理基础设施和业务的核心工具。监控也是必需的,应该和应用程序一起构建和部署。没有监控,你将无法了解你的系统环境、进行诊断故障、制定容量计划,也无法向组织提供系统的性能、成本和状态等信息。
关于监控,我们前面提到的Google服务层次结构图就是一个很好的阐述(如图1-1所示)。
但是监控没有那么容易实施,如果你监控了错误的东西或者使用了错误的方式,那么监控系统的价值将大大降低,这里列举了一些关于监控的反模式和解决方案。

1.2.1 事后监控

对于任何应用程序开发方法,在构建之前确定要构建的内容都是个好主意。遗憾的是,有一种常见的反模式,即将监控和其他运维工作(比如安全性)视为应用程序的增值组件而非核心功能。与安全性一样,监控也应该是应用程序的核心功能。如果你要为应用程序构建规范或用户故事,那么务必先把应用程序每个组件的监控指标考虑进来,千万不要等到项目结束或部署之前再做这件事情。我保证你会错过一些需要监控的东西。
带你读《Prometheus监控实战》之一:监控简介

图1-1 服务层级

提示:
有关如何简化此过程的建议,请参阅下面关于自动化和自服务的讨论。

1.2.2 机械式监控

许多环境都会为所有应用程序建立货物崇拜(Cargo Cult)式的监控系统。团队始终复用他们过去使用的检查机制,而不会为新系统或应用程序进行更新。一个常见的例子是监控每台主机上的CPU、内存和磁盘,但不监控可以指示主机上应用程序是否正常运行的关键服务。如果应用程序在你没有注意到的情况下发生故障,那么即使进行了监控,你也需要重新考虑正在监控的内容是否合理。
根据服务价值设计自上而下的监控系统是一个很好的方式(如图1-2所示),这会帮助明确应用程序中更有价值的部分,并优先监控这些内容,再从技术堆栈中依次向下推进。
带你读《Prometheus监控实战》之一:监控简介

图1-2 监控设计

从业务逻辑和业务输出开始,向下到应用程序逻辑,最后到基础设施。这并不意味着你不需要收集基础设施或操作系统指标—它们在诊断和容量规划中很有帮助—但你不太可能使用这些来报告应用程序的价值。
注意:如果无法从业务指标开始,则可试着从靠近用户侧的地方开始监控。因为他们才是最终的客户,他们的体验是推动业务发展的动力,了解他们的体验并发现他们何时遇到问题本身就很有价值。

1.2.3 不够准确的监控

这个反模式的一个常见形式是虽然监控了主机上的服务状态,但不够准确。例如,通过检查HTTP 200状态码可以监控Web应用程序是否正常运行,它会告诉你应用程序正在响应请求,但并不会反映出是否返回了正确的数据。
因此需要找准服务监控的内容—例如,监控业务事务的内容或速率,而不是监控它运行的Web服务器的运行时间。你会获得两种好处:如果服务因配置错误、程序bug或受损而导致内容不正确,你会及时查看到;而如果内容因底层Web服务而出现错误,你同样也会知道。

1.2.4 静态监控

另一种反模式是使用静态阈值—例如,如果主机的CPU使用率超过80%就发出警报。这种检查通常是不灵活的布尔逻辑或者一段时间内的静态阈值,它们通常会匹配特定的结果或范围,这种模式没有考虑到大多数复杂系统的动态性。阈值的匹配或许很重要,但它可能由异常事件触发,甚至可能是自然增长的结果。
静态阈值几乎总是错误的。数据库性能分析供应商VividCortex的首席执行官Baron Schwartz对此评论道:它们比一个停摆的时钟更糟糕,至少时钟每天还会有两次准的时候。任何给定系统的阈值都是错误的,因为所有系统都略有不同,并且在任何给定时刻也都是错误的,因为系统在经历不断变化的负载和其他情况。
为了更好地监控,我们需要查看数据窗口,而不是静态的时间点,需要使用更智能的技术来分析指标和阈值。

1.2.5 不频繁的监控

对于许多监控工具来说,设定监控周期都是一项挑战,一般默认检查周期设置了一个较大的值—例如,每隔5~15分钟仅检查一次应用程序。这通常会导致检查之间发生的关键事件丢失。你应该频繁地监控应用程序,以获得以下好处:

  • 识别故障或异常。
  • 满足响应时间预期—你绝对希望在用户报告故障之前找到问题。
  • 提供更细颗粒度的数据,以识别性能的问题和趋势。
  • 始终记住存储足够多的历史数据可以有效地帮助识别性能的问题和趋势。在很多情况下,这可能只需要数天或数周的数据—但如果丢弃了这些数据,则可能无法识别出趋势或发现重复出现的问题。

1.2.6 缺少自动化或自服务

监控系统很差或者没能正确实施的常见原因是它很难实现。如果你让应用程序开发人员觉得监测应用程序、收集数据或可视化很难完成,那么他们可能就不会去做这些事。如果监控的基础设施是手动维护的,或者过于复杂,那么由此产生的问题将导致监控系统落后或者发生故障,然后你会花费更多的时间来修复和维护监控系统,而不是监控这件事本身。
应尽可能使监控系统的实施和部署自动化:

  • 应该由配置管理进行部署。
  • 主机和服务的配置应该通过自动发现或自助提交来进行,这样可以自动监控新的应用程序,而不需要人为添加。
  • 添加检测应该很简单,并且是基于插件模式,开发人员应该能够把它放置到库中,而不必自己配置它。
    数据和可视化应该是自服务的。每个需要查看监控输出的人都应该能够查询和可视化这些内容。(这并不是说你不应该为人们构建仪表板,而是如果他们想要更多,他们就不应该问你。)

1.2.7 监控模式总结

一个良好的监控系统应该能提供以下内容:

  • 全局视角,从最高层(业务)依次展开。
  • 协助故障诊断。
  • 作为基础设施、应用程序开发和业务人员的信息源。

同时它也应该是:

  • 内置于应用程序设计、开发和部署的生命周期中。
  • 尽可能自动化,并提供自服务。

注意:
这种对监控系统“良好”的定义与另一个新出现的术语“可观察性”是交叉重叠的。你可以在Cindy Sridharan的精彩博客文章中看到更多相关信息,了解两者之间的差异。

1.3 监控机制

监控的方法是多种多样的,实际上,你可以说从单元测试到检查清单(checklist)的所有事情都是监控的某种形式。
注意:Lindsay Holmwood对测试驱动的监控有一个很好的介绍,讨论了测试和监控之间的联系。此外,Cindy Sridharan关于微服务测试的文章也介绍了一些有趣的测试和监控的相似之处。
但是传统上,监控的定义侧重于检查和测量应用程序的状态。

1.3.1 探针和内省

监控应用程序主要有两种方法:探针(probing)和内省(introspection)。探针监控是在应用程序的外部,它查询应用程序的外部特征:监听端口是否有响应并返回正确的数据或状态码。探针监控的一个例子是执行ICMP检查并确认可以收到响应。Nagios就是一个主要基于探针监控的监控系统。
内省监控主要查看应用程序内部的内容。应用程序经过检测,并返回其状态、内部组件,或者事务和事件性能的度量。这些数据可准确显示应用程序的运行方式,而不仅是其可用性或其表面行为。内省监控可以直接将事件、日志和指标发送到监控工具,也可以将信息发送给状态或健康检查接口,然后由监控工具收集。
内省方法提供了应用程序实际运行的状态,它允许你传达比探针监控更丰富且更多的有关应用程序状态上下文的信息,是能提供你和业务所需的监控信息的更好方式。
这并不是说探针监控没有作用了,了解应用程序的外部状态通常很有用,特别是如果应用程序由第三方提供,并且你没有深入了解其内部操作的时候。从外部查看应用程序以了解某些网络、安全性或可用性问题通常也很有帮助。通常建议对安全网络进行探针监控以发现问题,然后使用内省监控进行报告和诊断。我们将在第10章更多地介绍探针监控。

1.3.2 拉取和推送

目前有两种执行监控检查的方式,分别是拉取(pull)和推送(push),这里我们简单讨论一下。
基于拉取的监控方式会提取或检查远程应用程序—例如包含指标的端点,或是探针监控中使用ICMP进行的检查。在基于推送的监控方式中,应用程序发送事件给监控系统接收。
这两种方法都有利有弊。关于这些优点和缺点,监控领域内部存在相当大的争议,但就许多用户而言,这些辩论没有实际意义。Prometheus主要是一个基于拉取的系统,但它也支持接收推送到网关的事件,我们将在本书中展示如何使用这两种方法。

1.3.3 监控数据的类型

监控工具可以收集各种不同类型的数据,这些数据主要有两种形式:

  • 指标:大多数现代监控工具都非常依赖指标来帮助我们了解系统的情况。指标存储为时间序列数据,用于记录应用程序度量的状态,我们很快就会看到更多相关内容。
  • 日志:日志是从应用程序发出的(通常是文本的)事件。虽然有助于让你知道发生了什么,但它们通常对故障诊断和调查最有帮助。我们不会在本书中详细介绍日志,但是有很多可用的工具(如ELK堆栈)可用于收集和管理日志事件。

我写了一本关于你可能感兴趣的ELK堆栈的书。
由于Prometheus主要关注收集时间序列数据,因此接下来让我们更深入地了解指标。

1.4 指标

指标似乎始终是任何监控体系结构中最直接的部分。然而,有时候我们并没有投入足够的时间来理解我们正在收集的内容,为什么要收集它们,以及我们对这些指标做了些什么。
许多监控框架的重点都是故障检测,即检测是否发生了特定的系统事件或处于什么状态(这是Nagios的风格)。当收到有关特定系统事件的通知时,我们通常会查看收集到的任何指标,以找出发生的确切情况及其原因。在这个思路下,指标被视为故障检测的副产品或者补充。
请参阅本章后面有关通知设计的讨论,以了解为什么这是一个具有挑战性的问题。
Prometheus改变了“指标作为补充”的观念,指标变成了监控工作流程中最重要的部分。Prometheus颠覆了以故障检测为中心的模型,指标用来反映环境的状态、可用性以及性能。
当指标可以提供有关状态和性能的信息时,本书通常避免重复布尔状态检查。
正确使用指标可以提供基础设施的动态实时信息,帮助你管理和做出有关系统的最佳决策。此外,通过异常检测和模式分析,指标有可能在故障或问题发生之前,或者是在特定系统事件导致系统瘫痪之前就有所察觉。

1.4.1 什么是指标

由于指标和度量对监控框架至关重要,因此我们将帮助你了解到底什么是指标以及如何使用这些指标。这里我们以一个通俗易懂的方式,让你了解不同类型的指标、数据和可视化对我们的监控框架有何贡献。
指标是软件或硬件组件属性的度量。为了使指标有价值,我们会跟踪其状态,通常记录一段时间内的数据点。这些数据点称为观察点(observation),观察点通常包括值、时间戳,有时也涵盖描述观察点的一系列属性(如源或标签)。观察的集合称为时间序列。
时间序列数据的典型示例是网站访问或点击。我们定期收集有关网站点击量的观察点,记录点击次数和查看次数。我们还可能收集诸如访问来源、被访问到的服务器或其他各种信息等的属性。
我们通常以固定的时间间隔收集数据,该时间间隔被称为颗粒度(granularity)或分辨率(resolution),取值可以从1秒到5分钟,甚至到60分钟或更长。正确地选择指标的颗粒度至关重要,若选择得太粗糙,则很容易错过某些细节。例如,以5分钟为间隔对CPU或内存使用情况进行采样,几乎不可能识别出数据中的异常情况。另外,如果颗粒度过于精细,则需要存储和分析大量数据。
时间序列数据是这些观察点按时间顺序排列的集合。时间序列指标通常被可视化为二维图形,其中x轴是时间,y轴是具体的数据值(如图1-3所示)。通常,你会在y轴上看到多个数据值—例如,来自多个主机的CPU使用率值,或者成功和失败的事务。
这些图形非常有用,它们提供了相对容易理解的关键数据的直观展示,比使用列表形式的相同数据更加有效。图形还向我们展示了正在监控的任何历史节点,包括发生变化的内容和时间。我们可以使用这些功能来了解系统中发生的事情及其对应的时间。
带你读《Prometheus监控实战》之一:监控简介

图1-3 图形示例

1.4.2 指标类型

监控指标包含多种类型。
测量型
第一种指标类型是测量型(gauge),这种类型是上下增减的数字,本质上是特定度量的快照。常见的监控指标如CPU、内存和磁盘使用率等都属于这个类型。对于业务指标来说,指标可能是网站上的客户数量(如图1-4所示)。
带你读《Prometheus监控实战》之一:监控简介

图1-4 测量型指标示例

计数型
第二种类型是计数型(counter),这种类型是随着时间增加而不会减少的数字。虽然它们永远不会减少,但有时可以将其重置为零并再次开始递增。应用程序和基础设施的计数型示例包括系统正常运行时间、设备收发包的字节数或登录次数。业务方便的示例可能是一个月内的销售数量或应用程序收到的订单数量(如图1-5所示)。
在图1-5的示例中,有一个计数型指标在一段时间内递增。
计数型指标的一个优势在于它们可以让你计算变化率。每个观察到的数值都是在一个时刻:t,你可以使用t + 1处的值减去t处的值,以获得两个值之间的变化率。通过了解两个值之间的变化率,可以理解许多有用的信息。例如登录次数指标,你可以通过计算变化率来查看每秒的登录次数,这有助于确定网站这段时间的受欢迎程度。
带你读《Prometheus监控实战》之一:监控简介

图1-5 计数型指标示例

直方图
直方图(histogram)是对观察点进行采样的指标类型,可以展现数据集的频率分布。将数据分组在一起并以这样的方式显示,这个被称为“分箱”(binning)的过程可以直观地查看数值的相对大小。统计每个观察点并将其放入不同的桶中,这样可以产生多个指标:每个桶一个,加上所有值的总和以及计数。
通常,频率分布直方图看起来像条形图(如图1-6所示)。
带你读《Prometheus监控实战》之一:监控简介

图1-6 直方图指标示例

示例是身高频率分布的样本直方图。x轴是身高的分布,y轴是对应的频率值,例如可以看到身高160~165cm对应的值是2。
注意:还有另一种指标类型,称为“摘要型”(summary),类似于直方图,但它还会计算百分位数。更多信息请参考https://prometheus.io/docs/practices/histograms/
直方图可以很好地展现时间序列数据,尤其适用于数据的可视化(如应用程序延迟等)。

1.4.3 指标摘要

通常来说,单个指标对我们价值很小,往往需要联合并可视化多个指标,这其中需要应用一些数学变换。例如,我们可能会将统计函数应用于指标或指标组,一些可能应用的常见函数包括:

  • 计数:计算特定时间间隔内的观察点数。
  • 求和:将特定时间间隔内所有观察点的值累计相加。
  • 平均值:提供特定时间间隔内所有值的平均值。
  • 中间数:数值的几何中点,正好50%的数值位于它前面,而另外50%则位于它后面。
  • 百分位数:度量占总数特定百分比的观察点的值。
  • 标准差:显示指标分布中与平均值的标准差,这可以测量出数据集的差异程度。标准差为0表示数据都等于平均值,较高的标准差意味着数据分布的范围很广。
  • 变化率:显示时间序列中数据之间的变化程度。

以上是摘要方法的简要介绍,我们将在本书后面的章节中更为详细地介绍此部分内容。

1.4.4 指标聚合

除了上述的指标摘要外,你可能经常希望能看到来自多个源的指标的聚合视图,例如所有应用程序服务器的磁盘空间使用情况。指标聚合最典型的样式就是在一张图上显示多个指标,这有助于你识别环境的发展趋势(如图1-7所示)。例如,负载均衡器中的间歇性故障可能导致多个服务器的Web流量下降,这通常比通过查看每个单独的指标更容易发现。
带你读《Prometheus监控实战》之一:监控简介

图1-7 指标聚合示例

从图中可以看到30天内多个主机的磁盘使用情况,它为我们提供了一种快速确定某组主机的当前状态(和变化率)的方法。
最终,你会发现单一指标和聚合指标的组合可以提供最佳的健康视图:前者可深入到某个特定问题,而后者可以查看更高阶的状态。
接下来让我们更深入地了解指标摘要:使用(或者不使用)这些摘要的原因,以及如何使用平均值、中间数、标准差、百分位数和其他统计计算。
这是对某些统计技术的概述,而不是对主题的深入研究。对于具有较强的统计学或数学背景的人来说,对这些主题的探索可能显得过于简单。
平均值
平均值是标准的指标分析方法。实际上,几乎所有曾经监控或分析过网站及应用程序的人都会使用平均值。
例如,在网站运营领域,许多公司的生死存亡都取决于其网站或API的平均响应时间。
平均值很有吸引力,因为它们很容易计算。假设现在我们有一个包含七个时间序列值的列表:12、22、15、3、7、94和39。为了计算平均值,我们将值列表相加求和然后除以列表值的数量。
(12 + 22 + 15 + 3 + 7 + 94 + 39)/ 7 = 27.428 571 428 571
首先将七个值相加得到总和192,然后我们将总和除以值的数量,这里是7,以返回平均值:27.428 571 428 571。看起来很简单,对吧?但是,“魔鬼”都隐藏在细节中。
平均值假设事件都是正常的或者说你的数据是正态(或高斯)分布的—例如,在我们的平均响应时间中,假设所有事件以相同的速度运行或响应时间分布大致为钟形曲线,但应用程序很少出现这种情况。事实上,有个古老的统计学笑话(如图1-8所示),一位统计学家跳进平均深度只有10英寸(约25厘米)的湖中,然后差点被淹死……
为什么他差点会被淹死?因为湖中有大面积的浅水区和一部分深水区,由于浅水区面积较大,因此导致平均深度总体较低。同样的原则也适用于监控领域:高峰或低谷可能被平均值掩盖了。这些隐藏的异常值可能意味着,当我们认为大多数用户都享受着高质量的服务体验时,实际上很可能并非如此。
让我们看一个使用网站请求平均响应时间的示例(如图1-9所示)。
这里我们有一个图表显示了许多请求的响应时间,计算平均响应时间为4.1秒,这意味着绝大多数用户将体验到(可能)正常的4.1秒响应时间。但是,许多用户的响应时间要比这个时间长,甚至达到12秒,这是很难接受的。
让我们再看一个值分布更为广泛的例子(如图1-10所示)。
带你读《Prometheus监控实战》之一:监控简介

图1-8 平均值的缺陷(版权归Jeff Danziger所有)

带你读《Prometheus监控实战》之一:监控简介

图1-9 平均响应时间示例1

带你读《Prometheus监控实战》之一:监控简介

图1-10 平均响应时间示例2

这次我们的平均值将是一个不那么理想的6.8秒。但更糟糕的是,这个平均值比大多数用户收到的响应时间要好得多,因为请求时间大约分布在为9秒、10秒和11秒。如果我们仅依靠平均值,则可能会认为应用程序的性能比真实情况要好得多。
中间数
那什么是中间数呢?中间数处在所有数值的正中心:正好50%的数值位于它前面,而另外50%则位于它后面。如果有奇数项个值,则处于中间位置的值即为中间数。对于前面提到的数据集(12、22、15、3、7、94和39)来说,中间数为3。如果存在偶数项个值,则中间数将是中间两个值的平均值。因此,如果我们从数据集中删除39让数值变成偶数个,则中间数将变为9。
我们将它应用于之前的两张图(如图1-11所示)。
我们可以看到第一个示例中的中间数为3,为数据提供了更乐观的表示。而在第二个示例中,中间数是8,稍微好一点但足够接*均值以使其无效(如图1-12所示)。
你可能又发现这里的问题了,就像平均值一样,当数据分布呈钟形曲线时,中间数效果最好,但在真实环境中这是不现实的。
识别性能问题的另一种常用技术是根据平均值来计算指标的标准差。
带你读《Prometheus监控实战》之一:监控简介

图1-11 响应时间的平均值和中间数示例1

带你读《Prometheus监控实战》之一:监控简介

图1-12 响应时间的平均值和中间数示例2

标准差
正如我们在本章前面所学到的,标准差衡量数据集的变化或分布。标准差为0表示大部分数据接*均值,标准差越大意味着数据越分散。标准差由正或负加上sigma符号表示,例如,1 sigma表示与平均值有一个标准差。
然而,与平均值和中间数一样,当数据呈正态分布时,标准差最有效。在正态分布中,有一种简单的方式来阐明分布:经验法则,也称为68-95-99.7法则或3 sigma法则(如图1-13所示)。法则指出,一个标准差或1到–1代表平均值两边68.27%的数据,两个标准差或2到–2代表95.45%,而三个标准差则代表99.73%。
带你读《Prometheus监控实战》之一:监控简介

图1-13 经验法则

许多监控方法都会利用经验法则,当出现超过平均值两个标准差的事务或事件时触发警报,以捕获性能的异常值。然而,在之前的两个例子中,标准差并没有太大帮助。如果数据不是正态分布的,那么最终的标准差可能会误导你。
到目前为止,上述方法在识别异常数据方面没有提供很大帮助,但我们没有失去希望!下一个统计方法(百分位数)让我们看到了一丝曙光。
百分位数
百分位数度量的是占总数特定百分比的观察点的值。从本质上讲,它们会展示数据集的分布。例如,我们在上面看到的中间数是50百分位数(或p50)。对于中间数(已排好序的数据)来说,50%的值低于它,50%高于它。对于指标而言,百分位数很有意义,因为它们可以清晰地展现数值的分布。例如,一个事务的99百分位数为10毫秒,这很容易理解:99%的事务在10毫秒或更短时间内完成,1%的事务处理时间超过10毫秒。
百分位数是分位数的一种。
百分位数是识别异常值的理想选择。如果响应时间小于10毫秒表示你网站上的一个良好体验,那么99%的用户都是这样的—但其中1%的用户没有。一旦意识到这一点,你就可以专注于解决造成那1%的性能问题。
让我们将其应用到之前的请求和响应时间图表,看看会发生什么。将75和99百分位数应用于第一个示例数据集,如图1-14所示。
带你读《Prometheus监控实战》之一:监控简介

图1-14 响应时间的平均值、中间数和百分位数示例1

我们看到p75是5.5秒,这表明75%的请求在5.5秒内完成,25%比这个要慢,这与之前的分析基本相符。另一方面,p99为10.74秒,意味着99%的用户的请求响应时间少于10.74秒,剩余1%则超过10.74秒。百分位数展现了应用程序运行的真实情况。此外,我们还可以分析p75和p99的分布。如果我们很满意99%的用户获得10.74秒或更快的响应时间,而1%的用户比这更慢,那么我们就不需要考虑任何进一步的调整。而如果我们想要一致的响应时间,或者想要所有数据都低于10.74秒,那么现在便已经明确了可以跟踪、分析和改进的事务。在调整性能时,也能够看到p99响应时间的改善。
通过第二组数据可以看得更加清晰,如图1-15所示。
带你读《Prometheus监控实战》之一:监控简介

图1-15 响应时间的平均值、中间数和百分位数示例2

从图中可以看出p75为10秒,p99为12秒,其中p99清晰地显示了响应时间的广泛分布,这更准确地反映了网站的运行情况。我们现在了解到(与平均响应时间相反)并非所有用户都感受到了优质的体验。我们可以使用此数据来识别可能需要改进的应用程序模块。
然而,百分位数并不是完美的。我们建议绘制几种指标组合,以获得更清晰的数据图。例如,在测量延迟时,最好可以展示以下几项内容:

  • 50百分位数(或中间数)
  • 99百分位数
  • 最大值

添加最大值有助于可视化所测量指标的边界,虽然它也不完美:一个较高的最大值可以使图中的其他值显得渺小。
当开始构建检查和收集指标时,我们会应用百分位数和其他聚合指标,这会在后续章节进行介绍。

1.5 监控方法论

我们将在指标和指标聚合之上结合使用多种监控方法,以帮助加强监控。我们将结合以下两种监控方法:

  • Brendan Gregg的USE(Utilization、Saturation和Error)方法,侧重于主机级监控。
  • Google的四个黄金指标,专注于应用程序级监控。

监控方法提供的指导原则可以让你缩小范围并专注于所收集的海量时间序列中的特定指标。上述两个监控框架,一个侧重于主机级性能,一个侧重于应用程序级性能,结合使用可以获得一个相当全面的环境视图,帮助你解决任何问题。

1.5.1 USE方法

USE是使用率(Utilization)、饱和度(Saturation)和错误(Error)的缩写,该方法是由Netflix的内核和性能工程师Brendan Gregg开发的。USE方法建议创建服务器分析清单,以便快速识别问题。
可以利用从你的环境中收集的数据,对照清单来确定常见的性能问题。
USE方法可以概括为:针对每个资源,检查使用率、饱和度和错误。该方法对于监控那些受高使用率或饱和度的性能问题影响的资源来说是最有效的。让我们快速查看每个术语的定义以帮助理解。

  • 资源:系统的一个组件。在Gregg对模型的定义中,它是一个传统意义上的物理服务器组件,如CPU、磁盘等,但许多人也将软件资源包含在定义中。
  • 使用率:资源忙于工作的平均时间。它通常用随时间变化的百分比表示。
  • 饱和度:资源排队工作的指标,无法再处理额外的工作。通常用队列长度表示。
  • 错误:资源错误事件的计数。

我们将这些定义结合起来创建一份资源清单,并采用一种方法来监控每个要素:使用率、饱和度和错误。它们是如何起作用的呢?假设我们有一个严重的性能问题,想深入了解以便诊断。参考我们的清单并检查每个被监控组件的各个要素。在这个示例中,我们将从CPU开始:

  • CPU使用率随时间的百分比。
  • CPU饱和度,等待CPU的进程数。
  • 错误,通常对CPU资源不太有影响。

然后是内存:

  • 内存使用率随时间的百分比。
  • 内存饱和度,通过监控swap测量。
  • 错误,通常不太关键,但也可以捕获。

其他组件以此类推,直到我们找到了问题的瓶颈或信号。
我们将在第4章看到更多关于系统级别的指标介绍。
你可以查看Brendan Gregg提供的Linux系统的参考示例清单。

1.5.2 Google的四个黄金指标

Google的四个黄金指标来自Google SRE手册,它们采用与USE类似的方法,指定要监控的一系列通用指标类型。此方法中的指标类型主要关注的不是系统级的时间序列数据,更多是针对应用程序或面向用户的部分:

  • 延迟:服务请求所花费的时间,需要区分成功请求和失败请求。例如,失败请求可能会以非常低的延迟返回错误结果。
  • 流量:针对系统,例如,每秒HTTP请求数,或者数据库系统的事务。
  • 错误:请求失败的速率,要么是HTTP 500错误等显式失败,要么是返回错误内容或无效内容等隐式失败,或者基于策略原因导致的失败—例如,强制要求响应时间超过30ms的请求视为错误。
  • 饱和度:应用程序有多“满”,或者受限的资源,如内存或IO。这还包括即将饱和的部分,例如正在快速填充的磁盘。

黄金指标使用起来很简单。依次选择对应的高阶指标,然后为它们设置警报。如果其中一个指标出现问题,那么警报就会响起,然后你可以去诊断或解决问题。
我们将在第7章和第8章介绍应用程序监控时再次提到黄金指标。
Weaveworks团队开发了一个名为RED(Rate、Error和Duration)的相关框架,你可能也会对此感兴趣。

1.6 警报和通知

警报和通知是监控工具的主要输出。那么警报和通知之间有什么区别呢?警报会在某些事件发生(如指标达到阈值)时触发。然而,这并不意味着有人被告知此事件发生,这是通知的来源。通知接收警报并告知某人或某事:通过发送电子邮件、发送短信或者创建工单等。看起来这应该是一个非常简单的领域,但它通常包含很多复杂因素,并且很难实施和管理。
要建立一个出色的通知系统,需要考虑以下基础信息:

  • 哪些问题需要通知
  • 谁需要被告知
  • 如何告知他们
  • 多久告知他们一次
  • 何时停止告知以及何时升级到其他人

如果配置不当,导致生成了过多通知,那么人们将无法对它们采取任何行动,甚至可能将它们忽略掉。我们都有过这样的故事:收件箱中充满了来自监控系统的成千上万封通知邮件。有时,你会因为收到很多通知而出现警报疲劳,并且忽略它们(或者更糟糕的是,对通知邮件直接全选→删除)。因此,你可能会错过真正的重要通知。
最重要的是,你需要考虑通知内容。通常当出现问题或者有事件需要你注意时,通知是唯一的途径。它们需要简洁、清晰、准确,易于理解并且可操作。设计有价值、有意义的通知至关重要。让我们通过一个示例来看看通知内容为什么很重要。以下是Nagios关于磁盘空间的通知。

代码清单1-1 Nagios通知样例

带你读《Prometheus监控实战》之一:监控简介
想象一下,你刚刚在凌晨3点36分收到这条通知。它都告诉了你哪些信息?首先,这是一个主机磁盘空间警报,并且/data目录存储已达到91%。乍一看这很有价值,但实际上并没有那么实用。首先,这是由一个存储空间突增导致的?还是逐渐增长的结果?增长速度是多少?(1 GB分区上9%的可用磁盘空间与1 TB磁盘上9%的可用磁盘空间完全不同。)你可以忽略这类通知或将其静音吗?还是需要立即采取行动?如果没有其他上下文,那么采取的行动就会受到限制,你需要投入相当多的时间来收集上下文。
在我们的框架中,将重点关注以下内容:

  • 使通知清晰、准确、可操作。使用由人而不是计算机编写的通知在清晰度和实用性方面有显著差异。
  • 为通知添加上下文。通知应包含组件的其他相关信息。
  • 仅发送有意义的通知。

在这里给出的最简单的建议是记住“通知是供人而不是计算机阅读的”,请用心地设计它们。

1.7 可视化

数据可视化既是一门非常强大的分析和解释技术,也是一种令人惊叹的学习工具。指标及其可视化通常很难解释。人们在查看可视化图像时,往往会幻想出并不存在的事物间的联系:从随机数据中找到有意义的模式。这通常会导致从相关性到因果关系的突然飞跃,而数据的颗粒度或分辨率、表示数据的方式以及数据的规模可能会进一步加剧这种飞跃。
理想的可视化应该能够清晰地显示数据,突出重点而不仅是提高视觉效果。在本书中,我们不会看到很多可视化,但是一旦需要,我们会按照以下规则进行构建:

  • 清晰地显示数据
  • 引发思考(而不是视觉效果)
  • 避免扭曲数据
  • 使数据集保持一致
  • 允许更改颗粒度而不影响理解

上述内容很多都是从Edward Tufte的《The Visual Display of Quantitative Information》一书中获得的灵感,建议阅读该文章以帮助你构建良好的数据可视化。
Datadog团队也发布了一篇关于可视化时间序列数据的文章,同样值得一读。

1.8 另一本关于监控的书

正如许多人所知,我是Riemann的维护者之一,Riemann是一个专注于监控分布式系统的事件流处理器。我还写过另一本关于监控的书《The Art of Monitoring》,书中使用Riemann作为探索创新监控模式和方法的核心,并介绍了一种内省监控的架构(还有一些探针监控)。
在本书中,我将专注于基于拉取式的监控。我知道推送模型也有很多优势,但正如前面提到的,对于许多人来说,这些区别并没有意义。实际上,由于规模等问题,这两种方式的许多问题都不会影响实施。关于实施或工具选择的争论,并不会影响实施的成功。我强烈主张选择适合你的工具,而不建议未经审查便采用最新趋势或宣扬教条主义。
正因为很多人对此比较困惑,并且我也不希望自己的理念变得教条,所以我才有动力写就本书,它围绕着一种领先的基于拉取式的监控工具:Prometheus。在《The Art of Monitoring》中我写道:“也许看待这些工具选择的更好角度是,它们仅仅是实现本书中提出的监控理论的不同方法。它们都是树林里的树木。如果你发现其他工具更适合并达到同样的效果,那么我们很乐意听取你的意见。欢迎撰写博客文章、发表演讲或分享你的配置。”
因此,你将看到本书包含了《The Art of Monitoring》中的大部分方法论—事实上,本章的大部分内容都是它的精华。我们正在考虑把它的核心理念—更好的应用程序监控方法—应用于另一种不同的工具、架构和方法。

1.9 本书内容

本书会介绍关于监控的方法,然后使用Prometheus来实例化这些监控方法。在本书的最后,你应该可以搭建出一个高度可扩展的监控平台。
本书假定你要构建,而不是采购一个监控平台。有许多现成的软件即服务(SaaS)和基于云的监控解决方案可能适合你,甚至有一些托管的Prometheus方案。对于许多人来说,它们可能是更好的提案,因为他们才开始进行监控,还不需要投资建立自己的平台。但是我们认为,大多数人会随着他们环境和需求的增长,最终发现这些平台不太能满足他们的需求,然后会在内部构建监控系统。然而,是否真的需要还是要看实际情况。
在本书中,我们将循序渐进地介绍Prometheus监控平台,从监控主机和容器指标、服务发现、警报,到应用程序监控。本书内容将尝试覆盖到一些代表性的主流技术,但它们同样也适用于各种其他环境和技术堆栈。

1.10 小结

在本章中,我们介绍了现代监控方法,列举了几种监控实现的细节。我们讨论了监控的最佳实践和反模式,以及如何避免反模式的设计。
我们还详细介绍了时间序列数据和指标,细分并讲解了不同的指标类型。此外,本章还演示了一些应用在指标上的常见数学函数和聚合操作。
在下一章中,我们将介绍本书核心Prometheus,并对其架构和组件进行深入探讨。

上一篇:支持加密的开源笔记Joplin


下一篇:制作植物大战僵尸