目录
1 什么是监控
1.1 技术作为客户
1.2 业务作为客户
2. 监控基础知识
2.1 事后监控
2.2 机械式/模板式/无脑式监控
2.3 不够准确的监控
2.4 静态监控
2.5 不频繁的监控
2.6 缺少自动化或操作繁琐/不便
2.7 监控模式总结
3.监控机制
3.1 探针和内省
3.2 拉取和推送
3.3 监控数据的类型
4. 指标
4.1 什么是指标
4.2 指标类型
4.3 指标摘要
4.4 指标聚合
4.4.1 平均值
4.4.2 中间数
4.4.3 标准差
4.4.4 百分位数
5. 监控方法论
5.1 USE方法
5.2 Google的四个黄金指标
6. 警报和通知
7. 可视化
1 什么是监控
通常从技术角度来看,监控是衡量和管理技术系统的工具和流程。
但实际上,监控价值不止如此,它可以将系统和应用程序生成的指标转换成对应的业务价值。监控系统会将这些指标转换为衡量用户体验的依据,为业务提供反馈,确保为客户提供了所需的产品。监控不仅提供业务反馈,也提供对技术的反馈,指出哪些组件不起作用或者导致服务质量下降。
简而言之,监控系统有以下两个“客户”:
- 技术
- 业务
1.1 技术作为客户
监控系统第一个客户是技术,可能是研发、运维工程师、DevOps或者SRE。可以通过监控来了解技术环境状况,借用监控可以帮助检测、诊断和解决技术环境中的故障和问题。
同时,监控提供了大量的数据,帮助洞察关键的产品和技术决策,并衡量这些项目是否成功。监控也是产品管理生命周期以及内部客户关系的基础,有助于验证项目资金是否得到充分利用。
如有监控,且监控有效,就能拦截到线上很多的问题。
1.2 业务作为客户
业务是监控系统的第二个客户。监控系统是为了支撑业务,并确保业务持续开展。监控可以提供报告,使企业能够进行良好的产品和技术投资,有助于企业衡量技术带来的价值。
2. 监控基础知识
监控是管理基础设置和业务的核心工具。监控是必需的,应该和应用程序一起构建和部署。没有监控,相关人员无法了解系统环境、进行故障诊断、制定容量计划,也无法向组织提供系统的性能、成本和状态等信息。
好的监控实施不易,如果监控了错误的东西或者滥用监控,那么监控系统的价值将大大降低。以下列举监控的反例和解决措施。
2.1 事后监控
预则立,不预则废。监控也要在项目开发前考虑,很多不好的习惯喜欢在部署后进行监控指标设计。
与安全性一样,监控也应该是应用程序的核心功能。在为应用程序构建规范时,做概要设计时,务必考虑应用程序每个组件的监控指标。同时监控又是上线后的最后一个环节。
千万不要等到项目结束或者部署之前再做监控,否则可能有错过需要监控的指标的风险。
2.2 机械式/模板式/无脑式监控
许多公司或者团队始终复用它们过去使用的检查机制,而不会为新系统进行更新。常见的例子监控每台主机的CPU、内存和磁盘,但不监控可以知识主机上应用程序是否正常运行的关键指标(如返返回的HttpStatus、errorCode等与业务强相关的东西)。这种情况下的监控没有监控到关键的业务指标,收益不大,需要考虑监控的内容是否合理。
根据服务价值设计自上而下的监控系统是一个很好的方式,会帮助明确应用程序中更有价值的部分,并优先监控这些内容,再从技术堆栈中依次向下推进。
从业务逻辑和业务输出开始,向下到应用程序逻辑,最后再到基础设施。收集基础设施或操作系统/NODE指标可以协作定位问题以及容量规划,但不太能使用这些来报告应用程序的价值。切记不要机械式监控。
PS: 如果无法从业务指标开始,可以试着从靠近用户侧的地方开始监控。用户体验是推动业务发展的动力,了解它们的体验并发现它们合适遇到问题本身就很有价值。
2.3 不够准确的监控
这个监控中的大忌,常见形式是虽然监控了主机上的服务状态,但不够准确。比如监控HTTP项目,只通过检查Http 200的状态码衡量WEB应用程序是否征程运行,是不合理且不准确的。这种监控只会告诉应用程序正在响应请求,但不会反应业务是否返回了正确的数据。
所以需要找准服务监控的内容。比如监控业务的内容(Http返回的body)或者速率。这种情况下程序bug导致内容不正确马上能监控到。
2.4 静态监控
这种反例叫做静态阀值。常见如主机的CPU利用率超过80%就发出告警。这种检查通常是不灵活的布尔逻辑或者一段时间内的静态阈值,它们通常会匹配特定的结果或范围,这种模式有些情况还是较为适用,但是没有考虑到大多数复杂系统的动态性。
尽量不要用静态阈值,比较我们查看监控的时候,更喜欢查看数据窗口(如一段时间内的指标祈起伏变化的),而不是某个固定的时间点,需要使用更智能的技术来分析指标和阈值。笔者统计某些接口失败率,喜欢采用折线图,X轴是时间,Y轴是失败率,这样较为直观。
2.5 不频繁的监控
这种反例叫做不频繁的监控,即设置监控周期太长了(如每个2小时检查一次应用程序),导致检查之间丢失关键时间。合理设置监控周期,有以下好处:
- 识别故障或异常
- 满足响应时间预期——能在用户报告故障前找到问题。
- 提供更细粒度的数据,以识别性能的问题和趋势。
存储足够多的历史数据或者告警日志,能有效帮助识别性能的问题,解决偶现的重复问题。
2.6 缺少自动化或操作繁琐/不便
这也是一种反例。监控系统本身很难用,不方便用且使用门槛高的话,监测应用程序、收集数据或者可视化很难完成,那么应用程序开发人员会没有太多的使用欲望。
比如监控基础设施是经常挂不稳定的、手动维护的、过于复杂,由此可能产生问题,开发人员去配置这种复杂的监控规则是额外的工作量和负担。
应尽可能让监控系统的实施和部署自动化:
- 应该由配置管理进行部署,
- 主机和服务的配置应该通过自动发现或者自助提交来完成,这样的自动监控新的应用程序,而不需要人为添加。
- 添加检测应该很简单,而且是基于插件模式,开发人员应该能够把它放置在库中,或者使用图形化界面进行操作
- 数据和可视化应该是自助服务且有权限的。每个需要查看监控输出的人都应该能够查询和可视化这些内容。
2.7 监控模式总结
一个良好的监控系统能提供以下内容:
- 全局视角,从最高层(业务)依次展开。
- 协助故障诊断。
- 作为基础设施、应用程序开发和业务人员的信息源
- 内置于应用程序的设计、开发和部署的生命周期中
- 尽可能自动化,使用门槛低,能自己动手构建数据可视化。
3.监控机制
监控的方法有很多种,从单元测试、集成测试、冒烟测试或者是检查线上日志都可以算作监控的某种形式。监控和测试有一定的关联关系。
传统意义上,监控的定义侧重于检查和衡量应用程序的状态。
3.1 探针和内省
监控应用程序主要有两种方法:探针(probing)和内省(introspection)。探针监控是在应用程序的外部,通过查询应用程序的外部特征,如监控端口是否响应并返回正确的数据或状态码。K8S检查服务是否存活就是用的探针。Nagios也是一个主要基于探针监控的监控系统。
内省监控主要查看应用程序内部的内容。应用程序经过检测,并返回状态、内部组件,或者事务和事件性能的度量。这些数据可准确显示应用程序的运行方式,而不仅仅是其可用性或其表面行为。内省监控可以直接将事件、日志和指标发送到监控工具,也可以将信息发送给状态或者健康检查接口,然后由监控工具收集。Prometheus就是内省监控。
内省方法提供服务实际运行的状态,传递比探针监控更丰富的服务上下文信息,更贴近于实际业务指标。
这并不是说探针监控没有作用,了解应用程序的外部状态通常很有用,特别是如果服务由第三方提供,在没有深入了解其内部原理时,从外部查看服务的网络、安全性或可用性问题很有帮助。通常建议对安全网络进行探针监控以发现问题,使用内省监控进行报告和诊断。
3.2 拉取和推送
当前有两种执行监控检查的方式,即拉取(pull)和推送(push)。
基于拉取的监控方式会提取或检查远程应用程序——例如包含指标的端点,或者K8S探针检查。
基于推送的监控方式中,应用程序发送事件给监控系统接收。
两种方法有利有弊,没有绝对的好坏,使用过程中可以结合公司目前的技术栈进行抉择。
3.3 监控数据的类型
监控工具可以收集各种不同类型的数据,主要有以下两种形式:
- 指标:指标存储为时间序列数据,用于记录服务的状态,如接口请求次数、成功率、失败率等指标。
- 日志:日志通常是服务运行过程中产生的文件。ELK是常见的收集和管理日志的工具,可以在ELK做监控数据报表。
实际监控的过程中经常是指标+日志的方式进行监控。
4. 指标
指标在监控体系结构中相对直接,也常被视为故障检测的补充或手段。
但Prometheus改变了“指标作为补充”的观念,指标变成了检测工作流程中最重要的部分,也可以用来反应环境的状态、可用性以及性能。
正确使用指标可以提供基础设施的动态实时信息,有助于服务管理和做出有关系统的最佳决策。相信很多产品都问研发要过线上的运维指标,如日活、月活等指标,研发也关注过时延、成功率等指标,利用好指标能更好的优化服务。
同时,通过异常的检测和模式分析,指标有可能在故障或者问题发生前,就能提前察觉(比如CPU使用率持续攀高),最差也能在问题发生后立马能让相关人员有所反应。
4.1 什么是指标
指标是软件和硬件组件属性的度量。为了使指标有价值,我们会跟踪其状态,通常记录一段时间内的数据点。这些数据点称为观察点(observation),观察点通常包含值、时间戳,有时也涵盖描述观察点的一系列属性(如源或者标签)。观察的集合称为时间序列。
时间序列数据典型的范例是网站访问量、点击量等指标,在不同时间点记录不同的访问/点击数,组成对应的报表/折线图。
我们常以固定的时间间隔收集数据,该时间间隔被称为颗粒度(granularity)或者分辨率(resolution),取值可以从1S到5Min,甚至1H或者更长。合理选择指标颗粒度很重要,颗粒度越大容易错过细节。颗粒度越小,则需要存储和分析大量数据。
另外就是以图形展示指标比较直观,如统计服务总请求量时,X轴是时间,Y轴是各时间请求量大小。
4.2 指标类型
指标类型有很多种。
指标类型 | 说明 | 使用场景 |
测量型(gauge) | 是上下增减的数字,本质上是特定度量的快照。 | CPU使用率 内存使用率 磁盘使用率 网站客户数量 |
计数型(counter) | 随着时间增加而不会减少的数字。虽然永远不会减少,但有时可以将其重置为0并再次递增。 优势:可以让你计算变化率,并通过变化率理解很多有用信息。如登录次数指标,可以计算变化率查看每秒的登录次数,有助于确定网站在某个时间段受欢迎的程度。 | 用户登录次数 月销售商品数量 日收到订单数量 |
直方图 (histogram) | 是对观察点进行采样的指标类型,可以展现数据集的频率分布。将数据分组在一起并以这样的方式显示,这个被称为“分箱”(binning)的过程可以直观地查看数值的相对大小。 直方图可以很好地展现时间序列数据,尤其适用于数据的可视化,如请求时延分位。 | 身高频率分布样本直方图(x轴是身高分布,y轴是对应的频率值) 年龄人口分布样本直方图(x轴是年龄分布,y轴是对应的频率值) |
4.3 指标摘要
一般来说,单个指标对我们价值很小,往往需要联合并可视化多个指标,该过程需要应用一些数学变换。如将统计函数应用于指标或指标组,常见的函数如下:
- 计数:计算特定时间间隔内的观察点数。
- 求和:将特定时间间隔内所有观察点的值累计相加。
- 平均值:提供特定时间间隔内所有值的平均值。
- 中间数:数值的几何中点,正好50%的数值位于它前面,而另外50%则位于它后面。
- 百分位数:度量占总数特定百分比的观察点的值。
- 标准差:显示指标分布中与平均值的标准差,可以测量出数据集的差异成都。标准差为0表示数据都处于平均值,较高的标准差意味着数据分布的范围很广。
- 变化率:显示时间序列中数据之间的变化程度。
4.4 指标聚合
单一指标和聚合指标的组合可以提供最佳的监控视角,前者可以深入到某个特定问题,而后者可以查看更高阶的状态。
4.4.1 平均值
平均值是标准的指标分析方法。实际上,几乎所有曾经监控或分析过网站及应用程序的人都会使用平均值。许多公司的生死存亡都取决于网站或者api的平均响应时间。
缺点:平均值缺陷,如api的平均值只有3S,但可能有部分用户响应时间会达到5S以上。
4.4.2 中间数
中间数在真实环境中不太现实,全国人民收入的中间数并不能反映出贫富差距。
识别性能问题的另一种常用技术是根据平均值来计算指标的标准差。
4.4.3 标准差
标准差衡量数据集的变化或分布。
与平均值和中间数一样,当数据呈正太分布时,标准差最有效。在正态分布中,有一种简单的方式来阐明分布:经验法则,又称3-sigma法则或者68-95-99.7法则。
经验规则是统计规律,指出了在正态分布,几乎所有数据都将落在均值的三倍标准差内。所述经验规则表明,68%的数据将分布在的第一个标准偏差之内,95%将落在第二个标准差之内,和99.7%将落在均值的前三个标准偏差之内。
许多监控方法会利用经验法则,当出现超过两个平均值的标准差的事务或事件时触发警报,以捕获性能的异常值。但如果数据不是正太分布的,最终的标准差可能会误导人。
到目前为止,上述方法在识别异常数据方面没有提供很大帮助,但下一个统计方法(百分位数)存在可能。
4.4.4 百分位数
百分位数度量的事占总数特定百分比的观察点的值。从本质上来讲,是展示数据的分布。
我们在上面看到的中间数是50百分位数(或p50)。对于中间数(已排好序的数据)来说,50%的值低于它,50%高于它。对于指标而言,百分位很有意义,因为它可以清晰地展现数值的分布。一个API的99百分位数为10毫秒,就代表99%的API能在10毫秒或更短时间内完成,1%的API事务处理时间超过10毫秒。
百分位数是分位数的一种。
百分位数是识别异常值的理想选择。如上,如果99%的API都能在10毫秒返回,那我们专注于解决1%性能问题就好。当然普通的API能在10毫秒返回结果已经很快了。
另外测量延迟时,最好可以展示以下几项内容:
- 50百分位数(或中间数/50分位)
- 99百分位数(也叫99分位)
- 最大值
添加最大值有助于可视化所测量指标的边界,一个较高的最大值会使图中的其他值显得渺小。实际工作中,构建检查和收集指标时,常会以百分位数和其他指标聚合。
5. 监控方法论
在指标和指标聚合之上结合使用多种监控方法,以帮助加强监控。 我们将结合以下两种监控方法:
- Brendan Gregg 的USE(Utilization、Saturation和Error)方法,侧重于主机级监控。
- Google的四个黄金指标,专注于应用程序级监控。
5.1 USE方法
USE是使用率(Utilization)、饱和度(Saturation)和错误(Error)的缩写,该方法是Netfix的内核和性能工程师Brendan Gregg开发的。USE方法建议创建服务器分析清单,以便快速识别问题。
可以利用从你的环境中收集的数据,对照清单来确定常见的性能问题。
USE方法可以概括为:针对每个资源,检查使用率、饱和度和错误。以上术语详解如下:
- 资源:系统的一个组件,传统意义上的物理服务器组件,如CPU、磁盘等,当然也可以包含软件资源。
- 使用率:资源忙于工作的平均时间。它通常用随时间变化的百分比表示。
- 饱和度:资源排队工作的指标,无法再处理额外的工作。通常用队列长度表示。
- 错误:资源错误事件的计数。
将使用率、饱和度和错误等定义结合起来创建一份资源清单是常见的做法。但要采用一种方法来监控每个要素,有以下示例。
对于CPU:
- CPU使用率随时间的百分比。
- CPU饱和度,等待CPU的进程数。
- 错误,通常对CPU资源不太影响。
对于内存:
- 内存使用率随时间的百分比。
- 内存饱和度,通过监控swap测量。
- 错误,通常不太关键,但可以捕获。
其他组件以此类推,直到我们找到了问题的瓶颈或信号。
5.2 Google的四个黄金指标
Google的四个黄金指标来自Google SRE手册,指定了监控中的一系列指标类型。该方法中的指标类型主要关注的不是系统级的时间序列数据,更多的是针对应用程序或面向用户的部分:
- 延迟:服务请求所花费的时间,但需区分成功请求和失败请求。如失败请求可以在很短时间内返回结果。
- 流量:针对系统,如 每秒HTTP请求数,或者数据库系统的事务。
- 错误:请求失败的速率,要么是HTTP 500错误等显示失败,要么是返回错误内容或无效内容等隐形失败,或者基于策略原因导致的失败(如强制要求响应时间超过30ms的请求视为错误)。
- 饱和度:服务占用资源的程度,基于受限的资源,如内存或IO。还包括即将饱和的部分,如正在快速填充的磁盘。
黄金指标使用起来很简单,依次选择对应的高阶指标,然后为它们设置警报。如果其中一个指标出现问题,那么警报就会响起,然后你可以去诊断/解决问题。
PS:另外市面上还有RED的监控框架,即Rate、Error和Duration。
6. 警报和通知
监控工具的主要输出是警报和通知。
警报会在某些时间发生(如指标达到阈值)时触发。但并不意味着有人会被告知此事件的发生,通知会解决该问题。通过电子邮件、短信、微信、钉钉等手段,通知接收警报并告知某人或某事是业界常见的做法。
要建立一个优秀的通知系统,需要考虑以下基础信息:
- 哪些问题需要通知
- 谁需要被告知
- 如何告知他们
- 多久告知他们一次
- 何时停止告知以及何时升级到其他人
如果配置不当,或生成过多的通知,那么接收人员无法对它们采取任何行动,甚至可能将它们忽略掉。收件箱中来自监控系统的成千上万封通知邮件会造成警报疲劳,因此需要考虑通知的内容,让其简洁、清晰、准确、易于理解并且可操作。设计有价值、有意义的通知至关重要。
总结优秀的监控通知,需要考虑以下信息:
- 使通知清晰、准确、可操作。【谨记通知是人阅读的而不是计算机阅读的】
- 为通知添加上下文。通知应包含组件的其他相关信息。
- 仅仅发送有意义的通知。
7. 可视化
数据可视化是一门强大的分析和解释技术,也是一种令人惊叹的学习工具。理想的可视化应该能够清晰地显示数据,突出重点而不是仅仅提高视觉效果。
数据可视化可以参考以下规则进行构建:
- 清晰地显示数据
- 可视化数据能引发思考(而不仅仅是为了好看)
- 避免扭曲数据
- 使数据集保持一致
- 允许更改颗粒度而不影响理解