#注意#

监控和可监测性是能够帮助提升软件交付和绩效的能力。DORA DevOps 现状研究项目是对绩效提升的做法和能力进行的具有学术意义的独立而严谨的调查。


出色的监控是高绩效团队的支柱。DevOps 研究和评估 (DORA) 研究表明,全面的监控和可观测性解决方案及其相关技术实践有助于持续交付。

DORA 的研究定义了以下术语:

监控,是通过收集一组预定义的指标或日志帮助团队观察和了解系统状态的工具或技术解决方案。

可观测性,是通过探索预先定义的属性和场景,帮助团队有效调试其系统的工具或技术解决方案。

为能够取得很好的可观测性,您的团队必须具备如下的前提条件:

  • 系统整体运行状况报告(我的系统是否正常运行?我的系统是否有足够的可用资源?)。

  • 客户遇到的系统状态报告(我的客户是否知道我的系统是否停机,以及是否有糟糕的体验?)。

  • 监控关键业务和系统指标。

  • 可了解和调试生产环境中的系统工具。

  • 可用于查找您先前不知道的事情的相关信息的工具。

  • 访问有助于跟踪、了解和诊断生产环境中的基础架构问题的工具和数据(包括服务之间的互动)的权限。


01

如何实施监控和可观测性


监控和可观测性解决方案旨在实现以下目标:

  • 提供能够说明业务中断或服务降级的关键指标。

  • 检测业务中断、服务降级、故障或未授权的行为。

  • 对业务中断、服务降级、故障和未授权行为的辅助调试。

  • 确定容量规划和业务目标的长期趋势。

  • 揭示变更的负面影响。

与所有 DevOps 功能一样,工具本身并不能实现目标,但是工具可以辅助。监控系统不应局限于某个组织或某个团队使用。研发人员也必须能够熟练使用监控系统,才有助于形成数据驱动的决策文化,并持续改进系统的可调试性,从而减少业务中断。

有效实施监控和可观测性有几个要点。首先,监控系统应能针对业务中断进行告警,并能辅助原因分析从而避免故障升级。业务中断或服务降级影响的关键指标是恢复时间 (TTR)。能够有效降低TTR的关键因素是故障溯源和最快的业务恢复(这不一定是立即修复底层问题)。

概况来说,有两种方式了解系统:黑盒监控(没有掌握内部机制的情况下了解系统的内部状态)和白盒监控(掌握了内部机制的情况下了解系统的内部状态)。

如需了解详情,请参阅SRE一书中的“监控分布式系统”。

| 黑盒监控 |

在黑盒(或综合)监控系统中,通过公开API的HTTP调用,对外可访问的结点的RRC调用或者直接调用站点渲染网页等形式对系统模拟用户输入。

黑盒监控是一种基于采样的方法。黑盒监控和用户访问的是同样的系统。黑盒监控可以实现目标系统的外部请求的覆盖率。这既要对每个外部 API进行独立拨测 ,也要考虑典型用户场景的多API混合调用的拨测。例如,您可以对某个API 执行 100 次读取和仅 1 次写入。

通过调度系统控制拨测过程来实现足够的拨测频率,来确保监控的可信度。还应该有一个验证引擎,该验证引擎可以很简单的检查响应的返回码,也可以通过正则表达式去匹配整个输出,甚至对返回的页面进行渲染,然后遍历DOM对特定元素进行检查。验证后,需要存储上事件通知中需要的结果和元素据。诊断问题时查故障快照及其上下文是必要的。

| 白盒监控 |

监控和可观测性依赖于目标系统运行过程中发送出来的经过仔细核查过的数据,通常包含三种类型的数据:指标、日志和跟踪记录。某些监控系统还会跟踪和报告事件,这些事件表示了用户与系统的交互,或系统本身的状态变化。

指标,是在系统内部测量的结果,以可衡量的方式表示系统的状态。它们通常是三种类型的数值:Counters、Gauges和Distributions。在某些情况下也适合使用字符串指标,但通常需会使用数字指标,因为需要对其执行数学计算,以形成统计信息并进行可视化。

日志,是仅追加文件,可表示某个工作线程在特点时间点的状态。这些日志可以是单个字符串(如“User pushed button X”),可以是结构化条目包含元数据(如事件发生时间、处理事件的服务器和其他环境元素),也可以是类似于 [timestamp] [server] message [code] 的半结构化字符串,您可以根据需要在事后对其进行解析。通常使用SDK库(如 log4j、structlog、bunyan、log4net 或 Nlog)写日志。

日志处理是生成可信统计数据的可靠方法,因为即使日志处理系统本身存在错误,也可以根据存储的不可变日志重新处理它们。此外,还可以通过对日志的实时处理来生成基于日志的指标。

跟踪记录,由 span 组成,用于通过分布式系统跟踪事件或用户操作。span 可以显示一个请求通过一个服务器的路径,具有相同的两个span 可以并行运行。多个SPAN一起构成一个跟踪记录。剖析工具通常使用类似瀑布图来显示一个跟踪记录。这样,开发者就可以了解系统处理请求时在不同的服务器、队列和网络路劲中所花费的时间。

其中一个常见的框架是 OpenTelemetry,这是由 OpenCensus 和 OpenTracing 构成的。

指标、日志和跟踪记录可以由目标系统报告给监控系统,也可以通过三方平台上报给监控系统。

| 代码打桩 |

要实现监控系统,您的系统必须进行代码打桩。也就是说,系统中必须添加代码,公开内部状态。

例如,某个程序内嵌了一个连接池,则需要跟踪该池的大小和剩余的连接数量,为此,开发者必须在连接池逻辑中编写一些代码,跟踪连接的创建、销毁,分配,返还。数据上报可以通过日志或事件的形式,也可以在每次创建连接或者连接池扩大的时候去增加表示连接数的Counter或者增减表示剩余连接池队列大小的Gauge。

| 相关性 |

应用及其底层系统(例如 JVM、访客操作系统、Hypervisor、节点操作系统和硬件本身)都会关联指标。请注意,随着技术栈的深入,多个工作负载之间的指标会被关联起来。

例如,一个主机运行了多个应用,主机的磁盘用量无法与某个应用关联,但是,发现支撑系统上的各应用之间相似问题可以帮助您快速确定问题根因(例如磁盘速度变慢)。所以,从某个应用下钻到支撑系统,然后发现被支撑应用的类似问题,会很有用。

监控一个分布式系统意味着需要实现局部和整体的可观测。系统的构成可能是前端及其数据库,也可能是客户设备上运行的移动应用、云端负载均衡器和一组微服务。能够将不同来源的数据集中到一个地方并建立关联是现代可观测性工具的基本要求。

| 计算 |

基于从系统的各种来源收集的数据,生成统计信息或汇总各维度的数据。维度可能是用户类型、计算分区或客户区域。保存原始数据,能够动态计算各种维度的数据,但是也带来了存储的巨大开销。

插桩的设计中需要充分考虑基数和维度,因为这个因素对可观测系统的性能容量有很大的影响。

基数是衡量系统中不同值的指标。例如,cpu-utilization 等字段通常需要介于 0 到 100 之间的范围。但是,如果您跟踪用户的唯一标识符,则所有标识符都各不相同,因此,如果有 1M 个用户,则基数为 1M。这将带来巨大的改变。

维度是指同一个时间戳的同一个基数的多个值,通常可观测系统需要有一个时序数据库做支撑。仅记录计数器(例如 requests-sent)的值时,可能最初仅记录到此时间点(如{time=x, value=y})发送的请求数值。但是,与结构化日志一样,您可能还需要记录一些环境数据,结果如下所示:{time=x, value=y, server=foo, cluster=123,environment=prod,service=bar}。

结合使用多基数和多维度可能会导致计算和存储要求大幅增加,导致监控系统无法按预期执行!在向监控系统写入原始数据和动态数据时,开发者必须知悉这一点。

| 持续优化 |

从故障或错误中积累经验是系统运营的很重要的一部分。故障回顾或事后分析以及故障恢复的过程需要被存档。这样,才会持续优化我们的监控系统。

对于快速发展的公司来说,让组织内的任何人都能快速、高效地升级其监控系统至关重要。监控的配置管理也至关重要,需要像代码开发和发布一样有审核和审批流程去控制变更。对监控配置进行版本管理,是很好的起步,因为这很大程度决定着监控系统能够被广泛应用。通过自动化的流水线来发布部署监控配置,可以确保监控配置的正确性和一致性。

总之,将监控配置看成代码,通过自动化部署来发布变更,可以让团队成员使用的监控系统保持一致。


02

实施监控和可观测性的常见误区


在为公司开发监控和可观测性系统时,您应注意通常没有简单的开箱即用解决方案。任何正规监控系统都需要您深入了解要监测的每个组件,以及直接修改代码来对这些系统进行插桩。不要让单个监控人员或专职团队独立负责系统。这不仅会避免单点故障,也会提升整个公司了解和优化系统的能力。

监控和可观测性需要成为开发者的必备知识。这里常犯的错误是,仅有运营团队、NOC 或其他类似团队对监控系统进行更改。避免这种情况,并让监控系统的研发遵循CD模式。

在监控系统中常见的反模式,通过尝试枚举所有可能的错误情况并为每个条件编写代码发送告警。这种模式称为基于原因的告警,您应该尽可能避免这种情况。相反,您应该专注于基于用户影响的告警,即仅当面向用户可感知的影响或预测即将发生用户影响时才发送告警。当然,对于不直接面向用户的系统,也应该能够监控,但如果故障不影响到用户体验,不应给值班工程师发送告警通知。请注意,“面向用户”一词还可能包括您组织内部的用户。

告警通知时,需要考虑通知方式。应该有多条发给值班工程师的通知途径,包括但不限于短信、专用移动应用、自动电话呼叫或电子邮件。

一个常见的隐患是在通过电子邮件向整个团队发送告警通知时会因为责任不清而导致通知被忽略。

另一个常见的隐患是告警误报。如果太多告警通知不实用或不会产生任何改进,团队会很容易错过有意义和可能非常重要的通知,这是一个被称为告警麻木的问题。另外对告警屏蔽或告警抑制的策略都应非常仔细的确认,以确保不会被过度使用。

在构建监控仪表板时:

一个常见的错误是花费很长时间来策划“完美仪表盘”。这类似于上述基于原因的告警错误。在高效团队中,目标系统会快速变更,以致于完美仪表盘在完成策划之前都已过时。相反,专注于团队成员快速创建大屏或实现可视化需求的能力非常重要。

另外一个常见问题是,没有将面向产品或高管的指标(如用户获取率和收入跟踪)与系统监控状况指标分开。因为它们都非常重要,但又不同。强烈建议将这些分开。


03

如何衡量监控和可观测性


在为公司实施监控和可观测性系统时,您可以跟踪一些内部指标来评估效果。以下可以通过月度调查或事后自动化分析或告警日志来评估的一些指标示例。

对监控配置所做的更改。每周向包含监控配置的代码库发出多少次拉取请求或做了多少次更改?这些更改多久推送到监控系统一次?(每天?批处理?在 PR 上立即推送?)

“非工作时间”告警。夜间处理告警的百分比是多少?虽然一些全球企业都具有全天候值班,使得这本身不是问题,但这表明告警的关注度不够,夜间告警会使得告警麻木和消耗团队精力。

团队通知平衡。如果您有异地团队负责某项服务,则所有团队都会合理地分配和解决告警吗?如果不会,原因是什么?

告警误报。有多少告警未采取措施,或者被标记为“按预期执行”?应删除不实用和无助于预测故障的告警。

告警漏报。有多少系统故障没有被告警或延迟告警?您多久做一次事后分析,增加新的(基于用户影响的)告警?

告警数量。每周有多少个告警(总计或按严重性、团队等分组)?

告警确认。在规定的时间(如 5 分钟、30 分钟)内,被确认的告警百分比是多少?通常,会结合通知候选值班人员的次数和提醒失败次数。

告警屏蔽和屏蔽时长。每周有多少条告警被屏蔽?被新增屏蔽的告警有多少?被取消屏蔽的告警有多少?如果您的告警屏蔽有时效,那么有多少告警的屏蔽时间被延长?平均和最大告警屏蔽时间是多少?(一个非常有趣的问题是,“有多少个告警屏蔽实际上是‘无限期延长的’?”)

无效告警。有多少百分比的告警被视为“无效”?也就是说,收到告警的工程师无法立即采取某种措施,要么无法理解告警的意思,要么是已知问题。无效告警会增加工作量。

易用性:告警、runbook、仪表盘。 仪表板上有多少图表?每个图表有多少线条?团队能否理解图表?是否提供解释性文字来帮助新工程师?用户是否需要大量滚动和浏览才能找到所需信息?工程师能否实际从告警导航到playbook再到仪表盘?告警命名方式是否让工程师易理解?这些可通过调查问卷周期性的在团队进行调查。

MTTD、MTTR、影响。本质是故障检测时间、故障解决时间和影响。故障影响可以通过计算被影响的客户数量X被影响客户的时间来统计。故障影响可以通过工具更精确地评估。

通过跟踪指标,您可以更好地评估您的监控和可观测性系统对公司的效果。通过按产品、运营团队或其他方法细分这些衡量指标,您不仅可以深入了解产品的运行状况,还可以深入了解流程和人员。