作者:阳其凯(逸陵)、张江宇(九辩)
前言
Aliware
任何连续稳定运行的生产系统都离不开有效的监控与报警机制。通过监控,我们可以实时掌握系统和业务的运行状态;而报警则帮助我们及时发现并响应监控指标及业务中的异常情况。
报警在日常生活中随处可见,同时起到了关键的作用。在 IT 领域,告警同样是确保系统可靠性的基石。我们知道,没有任何一套IT系统能够达到 100% 的可靠性,因此我们的策略是不断提升服务的可靠性。为了实现这一目标并确保服务的连续性,有许多不同的路径可以选择。在深入分析这些路径之前,我们先来探讨一下 IT 系统的可用性及相关理论基础。
1.2.1 IT系统可用性
在讲解告警之前我们首先简单聊一下 IT 系统的可靠性。2017 年,ufried 在《Resilient software design in a nutshell》中,对 IT 系统可用性的定义如下:
那么,不难看出系统可用性的指标从 2 个方面,即 MTTF(不出故障的时间)和 MTTR(出故障后的恢复时间)
MTTR:全称是 Mean Time To Repair,平均修复时间。即系统出故障后的恢复时间,MTTR 越短表示易恢复性越好,系统可用性越高。
1.2.2 IT 系统稳定性建设理论
在 IT 系统稳定性建设中,稳定性建设的中心指导思想就是提高 MTTF(无故障时间)以及降低 MTTR(故障后的恢复时间)。
那么我们仔细来分析一下这个过程:
1)提高 MTTF:换言之,使用各种技术、流程机制等手段去规避故障的发生,降低故障的发生概率,尽可能提高业务的连续性。比如:
文化上:稳定性相关制度与文化的宣导、培训、考试等。
2)降低 MTTR:我们知道 MTTR 越短,表明系统故障恢复得越快,服务的可用性也就越高,MTTR 可以进一步细分为以下几个部分:MTTR = MTTI + MTTK + MTTF + MTTV。
在稳定性建设中,MTTR 的缩短是核心目标之一。而告警能力建设可以有效缩短 MTTI,同时好的告警体系建设同样可以助力缩短 MTTK 的过程,从而加快整个 MTTR 的进程。
1.2.3 安全生产理念
在数字化转型加速的当下,企业业务不断向数字化迈进,服务用户数量激增,导致 IT 系统的复杂性日益增加。特别是在政府和金融等行业,业务连续性和稳定性已成为制约发展的关键因素。微服务架构与容器化的引入虽然提高了应用的灵活性,但也带来了庞大而复杂的系统关系,使得故障频发且难以定位。针对这一挑战,阿里云推出了云原生安全生产解决方案。该方案以故障管理为核心,遵循“1-5-10”原则(即 1 分钟内发现问题、5 分钟内定位问题、10 分钟内恢复),并围绕故障生命周期的三个阶段——事前预防、事中快速响应及恢复、事后防止再发生,构建全面的应对机制。通过提供专业的技术咨询和支持,确保这些机制能够有效实施,从而保障业务持续稳定运行,并将资产损失控制在最低限度。
个人理解 1-5-10 安全生产体系本质上是对 MTTR(平均修复时间)的一种 SLA(服务水平协议)承诺。而我们今天关注的核心和主题是“告警”。告警在整个安全生产体系中扮演着至关重要的角色,它是 1-5-10 理念中第一个环节——1 分钟内发现问题(即 MTTI,平均检测时间)的具体体现。告警系统不仅能够及时发现潜在问题,还能迅速触发响应机制,确保在最短时间内定位并解决问题。因此,告警功能直接牵引着整个安全生产体系的运行,其效果直接影响到安全生产体系实施的成败。可以说,告警是保障系统稳定性和可靠性的基石。通过高效的告警机制,我们可以更早地识别和处理故障,从而最大限度地减少业务中断和资产损失。
告警体系建设通用流程
Aliware
首先我们分析一下完成系统监控报警的一般流程是什么样的?我们可以抽象为如下的几个环节:
首先,必须明确需要监控的对象,分析出哪些对象需要被监控。通过对系统进行分层梳理,识别出关键组件和服务,确保所有重要部分都不会被遗漏。在此基础上,对当前的监控配置进行逐层检查,查找不足之处,以提升系统的监控覆盖率。
其次,分析出监控这些对象的哪些维度和指标。通过监控对象分层梳理、对象的指标维度分析,综合监控的评价标准,得到业务系统配置监控所需的「对象和指标表」,为后续的监控实施奠定基础。
一旦确定了监控指标,接下来就是数据的采集工作。选定可靠的数据来源以及合适的采集周期,将监控指标的数据汇集至相关的可观测系统(如阿里云云监控、SLS、ARMS 等)。在此过程中,对采集到的数据进行必要的清洗和处理,最终借助可视化工具,以图表的形式展示数据,便于对系统状态进行直观分析和理解。
为实现全局视角下的监控覆盖,关键在于采用分层架构对监控对象进行全面梳理,识别各层级的关键监控要素。一个完备的监控体系通常包含以下层级结构:
分层 | |||
通过上述层级划分可见,不同层级的监控对象对业务连续性的影响程度呈现递减趋势。举例而言,单台服务器的异常可能不会直接影响业务运行,但核心业务流程(如订单处理)的故障必然导致业务中断。因此,在实际监控策略制定中,应依据层级重要性差异设置相应的告警级别和响应机制,将监控重点放在那些对业务影响较大的层面上。
监控对象需要进行数字化衡量,那么指标是最佳的度量方式与形态,通过指标与维度从而实现监控对象的分析。那么有哪些常用的指标呢?下面列举四大类常用“黄金指标”如下:
指标类型 | 数量和质量 | 指标示例 | |
基础设施层如:磁盘和网卡IO | |||
错误类型指标 | 对象发生错误情况 | 错误数、错误率 | |
延迟类型指标 | 请求对象所需时间情况 | RT、超时数、超时率 | |
饱和度类型指标 | 对象被利用的情况(总量有限) |
分层 | 对象 | 具体指标示例 | |
业务层(含终端体验层) | 业务本身(链路) | 流量、延迟、错误 | |
应用层 | 进程本身 | 错误、饱和度 | |
API接口 | 流量、延迟、错误 | ||
服务/系统依赖层 | 上下游依赖的系统 | ||
Kafka | 读写QPS、消费延迟、分区使用率、磁盘使用率等 | ||
RDS | 读写QPS、慢SQL、连接数、CPU使用率、内存使用率等 | ||
Redis | 读写QPS、RT、缓存命中率等 | ||
基础设施层 | |||
CPU | |||
MEM | |||
DISK | |||
端口 |
在指标分析中,维度分析是重要组成部分。常见的监控告警主要采用时间维度,即对比监控对象在时间序列上的变化。此外,属性维度也是重要的分析视角。
维度类型 | 维度类型描述 | |
时间维度 | 同一个对象的指标在时间前后的纵向对比 | |
属性维度 | 这里暂时不展开 |
在监控指标分析中,虽然单一维度的分析至关重要,但仅依赖单维度配置往往容易产生误告,或增加问题根因定位的复杂度。此时,采用多维度的告警策略显得更为合理。以应用的 QPS(每秒查询率)为例,如果仅基于固定阈值设置告警,可能会因流量波动或业务周期性变化而频繁触发误报。通过引入多维度分析(如结合时间趋势、业务场景、资源利用率等),可以更精准地识别异常,减少误告率,并提升问题排查效率。
以下针对 QPS 阈值场景进行细化分析,并结合 RT(响应时间)指标设计检测机制,列举几种典型场景及其应对策略:
2.4.1 告警设置基本原则
在进行告警规则配置之前,我们需要明确以下告警的基本原则。
告警具备真实性:告警的真实性是最为关键的原则。每一条告警都必须基于实际存在的问题或潜在风险,确保其能够真实地反映出服务当前的状态,而非偶发性波动或外部干扰。这样能及时预警并采取行动,避免更严重的问题发生。
告警需要持续优化:通过 PDCA 循环(Plan-Do-Check-Act)实现告警系统的自我进化与持续优化,我们应该持续对告警进行统计分析,对误报现象加以研究并采取有效应对措施,如屏蔽无效告警、简化信息反馈、调整阈值或更精准地反映异常原因。这是一个长期而持续的过程,需要不断迭代和完善。
以请求失败举例,如仅当请求的失败量超过某一阈值时告警,可能存在多种原因,如一些恶意构造的请求,也触发失败量告警。这样的告警既不具备真实性,也不具备可操作性,因为确实无需任何处理。对于此类情况,我们应该尽可能通过特性加以识别,从而更加精准地区分不同原因的告警,以提高告警的准确性和有效性。
2.4.2 告警等级定义
使用告警时,一个典型的问题就是告警信噪比低,工程师往往被海量低质量告警淹没,解决这类问题,有一个非常好的突破口就是定义告警等级标准。告警等级定义可以参考阿里巴巴集团关于故障级别的定义。这一方法的基本思路是根据预警的影响程度和业务特性来划分告警等级,从而确定信息传播的媒介、受众以及相应的标准操作流程(SOP)。通过这一方式,不同级别的告警可以被更合理地分类和处理,使得工程师能够迅速识别最关键信息,集中精力应对高优先级的问题。此外,建立清晰的告警等级体系还可以促进团队之间的沟通与协作,提高整体响应效率和质量。
在阿里云可观测系统(如 ARMS)中一般采用通用 P 等级进行衡量(P1、P2、P3、P4)。
如下为针对应用重要性进行划分,按照影响面进行告警的 P 级别定义参考的标准。
2)方式 2:按照主观进行 P 级定义
P4 | |
P3 | |
严重言行需要客户使用的产品的关键性系统问题 | |
P1 |
2.4.3 告警通知策略标准
上面提到了告警等级,依据告警等级以及告警触发场景进行分渠道通知,保障核心告警不被忽略,同时非核心告警可以在一定时间窗口响应,减少工程师响应疲劳度,提升工程师幸福度。阿里云可观测产品多种通知策略(如常用的语音、短信、邮件、IM 即时消息和群组通知),每种方式都有其特定的应用场景,具体如下表所示:
多群、多人联动等场景 |
P3 | |
P2 | |
P1 |
告警的几个重要问题
Aliware
在告警系统选型以及告警体系的建设当中,如下的几个问题需要重点关注。
在云原生时代,企业 IT 基础设施的规模越来越大,越来越多的系统和服务被部署在云环境中。为了监控这些复杂的 IT 环境,企业通常会选择使用异构监控系统,例如 Prometheus、Grafana、Zabbix 等,以获取更全面的监控数据,然而,这种异构监控系统也带来了一些问题,其中最显著的是告警信息的分散。由于不同的监控系统可能会产生不同的告警信息,这些信息可能会分散在各个系统中,导致企业很难全面了解其 IT 系统的告警状况。这使得响应告警变得更加困难,同时也增加了人工管理的复杂性和工作量。如何针对这些异构的告警事件进行管理是一个需要考虑的问题。如下是常见的几个潜在的场景:
场景一:
企业迁移上云后,云上产品的告警不统一
在一个典型的云原生业务应用部署架构中,通常会使用到如下产品 ACK、ECS、RDS,应用通过 Kubernetes 部署在阿里云的 ECS 上并访问云上的 RDS。在这个架构中通常会用到如下监控产品来对系统进行监控。
通过 SLS 对应用产生的日志进行监控,当日志出现异常时进行告警。
多云、混合云架构下,异构监控系统告警不统一
自研监控系统、自定义事件告警接入
在选择告警系统、配置告警规则的时候,告警误报是我们需要考虑的重要因素。理想中的告警,不存在误报(即本来正常的,告警为异常),出现告警就需要处理,如果误报的告警太多,处理的告警的同学会产生困扰、造成资源的浪费,同时也容易产生“狼来了”的问题。
告警一般是通过“现象”来判断,而是否有问题要看产生现象的原因判断。相同的现象引起的原因可能不同,这种“可能性”是导致误告警的最核心原因。如果能减少到唯一的原因或者尽可能少的原因,那就能很明确问题所在。
在告警系统的选型以及告警设置中,告警风暴问题的重要性尤为突出,每个研发/运维同学单日处理的告警数据量是有限的,如果产生告警风暴,重要的告警将会淹没,同时也会加剧运维同学的负担,降低幸福感。如下为常见的一些原则:
告警等级划分:将不同等级的告警进行分开管理;
过滤无关告警:基于预设的规则过滤掉不重要的告警;
使用压缩、静默等手段进行告警收敛,所以在告警系统选型的时候需要重点关注是否具备该项能力;
压缩:将匹配到的告警事件压缩为一个告警或者按照分组压缩为多个告警。可以进一步设置是否需要按照指定 Label 进行分组,每个分组有单独的告警触发、发送和恢复的生命周期,可以单独进行发送、恢复和管理。如下的是常见的几种压缩策略:
基于时间压缩:标签相同的告警如果开始时间和结束时间有交集,则会合并为一个告警事件,合并后的告警事件的开始时间和结束时间取这两个告警事件的并集。
当告警触发时,需要设计一套完整的处理机制,而不仅仅是简单的通知发送。一个完善的告警处理流程应包含认领、屏蔽、回调、标注、升级和关闭等关键环节,以确保告警得到有效管理和快速响应。
当告警触发后,相关人员可主动认领该告警,认领后相同告警将仅发送给认领人。这一机制旨在避免告警被多人重复处理,同时明确责任人,提升处理效率。认领状态支持取消,以便灵活调整处理人员。
针对已知问题或特定场景(如故障定位期间或服务发布过程中),可设置告警屏蔽规则,屏蔽期间相关告警将不再发送。屏蔽支持按周期或时间段配置,也可随时取消。此功能有效减少无效告警对运维人员的干扰,提升告警管理的精准性。
告警回调
告警规则可配置回调接口,当告警触发时自动执行预设的恢复操作。通过自动化手段快速恢复服务,缩短故障修复时间(MTTR),尤其在紧急情况下,能够显著提升系统可用性。
用户可对告警进行误报标注,记录告警是否为误报。误告标注的主要目的是通过标注让系统开发人员知道异常检测过程中,哪些点还需要提升优化,提高告警的准确性,为用户提供真实有效的告警提供保障。
案例分享
Aliware
某著名垂直电商 A 公司目前已经进入深度用云的阶段,公司目前面临如下的问题:
告警资源权责划分:公司云资源及应用分散在 30 多家供应商中,作为统一运维团队,需要在告警信息中明确标注资源归属,以便快速划分责任。同时,需将归属明确的告警信息及时传递给相应供应商,由其进行处理和响应。
方案的建设思路:
定制统一的告警管理大盘。
4.2.1 监控对象梳理
客户 A 的大部分资源都部署在阿里云上,整个的技术架构也是比较典型的电商微服架构体系,部分应用部署在阿里云容器服务 ACK 中,少部分应用由于技术或者客观原因部署在阿里云 ECS 上,底层中间件/存储使用了 RDS、MongoDB、Redis、Clickhouse、Kafka、RabbitMQ、ES、OpenSearch、Flink、SLS、OSS、NAS等,接入层使用了DDos、WAF、SLB(CLB)等。
按照分层设计(自上而下)的理念,用户进行如下的分层划分:
4.2.2 定标准
用户这里的定标准涉及多个方面,本质上都是立足安全生产,围绕业务高效、可靠、稳定的运行展开。
用户之前标签规范有多个版本(但是都存在一些问题),在进行交流后最后成型,关于标签的设计与最佳实践可以参考《一文详解阿里云可观测体系下标签最佳实践》。
日志规范
用户在日志规范部分详细地介绍了输出日志的原则与标准,这里摘录部分信息。
1、如何打印日志:
日志需接入阿里云SLS方便查询和分析,同时按照应用进行区分。
打印日志时一定要打印方便定位和排查的字段,例如用户的id,request内容等。
生产环境敏感信息进行mask打印。
手机号仅显示后四位(手机号有可能作为排查日志的唯一标记,建议保留后四位,如果有其他唯一标识,建议不打印手机号)。
用户邮箱不打印日志。
用户详细地址不打印日志。
涉及到钱账户的不打印日志,如银行卡、微信/支付宝账号。
开启日志Tracing功能,这样同一个请求会生成同样的trace,可以串联和分析整个请求链路。
调用第三方服务前,打印请求内容。
调用第三方服务后,打印原始返回结果。
操作数据库/Redis/Kafka后打印结果。
系统出现异常时,打印错误具体信息
核心业务计算时,打印重要步骤结果,方便出错时回溯计算流程。
经常会引起客诉的情况。
2、审计日志
敏感数据:上传、下载、查看敏感数据等动作。
敏感操作:删除、更新等动作。
3、日志等级
目前常见的日志分为四种,生产环境一般开启info及以上的日志,测试环境可以开始debug级别的日志
debug: 打印一些debug信息,比如每个步骤结果,主要是为了测试环境排查问题而用,生产环境一般只会打印info及以上。
info:常规的信息,例如接收到的请求。
warn:代码发现异常情况但又不影响业务逻辑继续情况,如某个重要参数为空(但不影响业务逻辑往下继续)
error:影响业务逻辑的异常情况,包括但不限于以下情况如调用第三方失败、接口参数校验失败、数据库/Redis/Kafka调用失败、系统异常。
日志需要按照应用/类型进行物理区分隔离,方便日志检索与告警设置。
4.2.3 标准实施
标准实施包含多个环节,如下为标签的实施细则,其他标准的实施不在这里展开。
标签关系的建立目前主要分为手工页面配置方式以及 API 方式,详细参考文档《一文详解阿里云可观测体系下标签最佳实践》。
其他:对于无法通过 API 或者页面配置的主要集中在容器场景,可以在对应的 yaml 中进行声明。
该部分主要为客户 A 运维团队在新应用、资源申请的时候,内部 SOP 中规定的一个必要步骤。为了防止有漏网之鱼,运维团队内部编写了定时脚本针对线上资源进行扫描,强制检查规范,对于不符合规范的资源进行通知以及通晒。
4.2.4 监控指标梳理
客户 A 主要使用云监控对云产品资源进行进行监控,按照分层梳理监控对象的里面重新进行监控的梳理,补齐相关缺失项,覆盖应用/前端监控(ARMS)、业务监控(使用 SLS 日志监控),如下为部分应用监控告警梳理截图,详细配置列表样例可以提工单联系 ARMS 服务账号。
4.2.5 报警配置
4.2.5.1 告警配置
客户 A 的报警配置主要集中在 ARMS(应用监控、Prometheus)、云监控以及日志服务上。
4.2.5.2 基于标签进行告警事件分发
通过在云资源上进行打标,进而在告警事件上支持相关标签,从而实现告警事件的分发。
图中为解决方案的示意图,其中阶段1&阶段2中的绿色部分表示阿里云当前已经支持的能力,灰色部分为正在支持中。
应用监控的告警规则需要打上这个标签 enrich_app_labels:true,这样应用标签和实例标签就会富化到对应的告警事件里面。然后自定义的应用标签会自动加上这个前缀:arms_app_lable_{自定义应用标签key},自定义的实例标签会自动加上这个前缀:arms_app_host_lable_{自定义实例标签key}。
用户的场景为配置相关容器的监控告警,Node、Service、Pod 等这些资源在部署的时候会严格按照规范带上相关的 label。如下为用户针对节点设置节点相关的报警“容器节点内存使用率超过 85%”。
告警中使用注释对告警进行打标,相关 node 的标从 kube_node_labels 获取。
值:可执行的 PromQL,支持通过 ${xxx} 引用告警中的标签,此处示例为 kube_node_labels{node=${node_name}},示例中使用了 ${node_name} 来引用节点名称。
结果:告警事件中会增加 node 相关的 label。
扩展案例:
通过Kubernetes Label分发告警
日志服务 SLS 的告警设置详细参考文档:https://help.aliyun.com/zh/sls/user-guide/sls-alerting/
由于用户在规范中定义了各个微服务应用按照不同的 logstore 进行区分,所以针对 logstore 的告警设置能够明确地知道当前日志归属于哪个应用。该部分目前采用静态标签(标注)进行设置如下所示:
当前云监控侧站点拨测不支持静态与动态打标的方式、基础云监控报警不支持动态标签的方式。目前可以支持将云服务接入 Prometheus[5], 使用 Prometheus 的方式进行绕开解决。
4.2.6 对接 ITSM
客户 A 采用 ARMS 作为统一告警管理平台[6],首先需要集成云监控以及 SLS 中的告警(ARMS 中告警默认支持), 最后进行通知策略的配置。
4.2.6.1 告警集成
修改云监控告警规则,将告警发送至 ARMS
日志服务创建 webhook 集成,在对应的 project 的告警中心创建 webhook 集成,用于告警回调
修改日志服务告警规则,将告警发送至 ARMS
ARMS 中配置通知策略,详细参考通知策略最佳实践
如下为客户 A 基于 ITSM 构建的告警事件统一大盘,通过该大盘用户能够直观将来自云监控、日志服务、ARMS 的告警事件进行集中的展示、管理。
总结
Aliware
本文围绕告警进行展开,重点讨论企业级告警体系构建的通用思路以及在进行告警系统选型或者建设中需要关注的重点问题,最后结合阿里云可观测产品给出线上客户的实践案例,希望能够为企业提供一套全面且实用的告警体系建设指南与参考。
参考文档:
https://my.oschina.net/u/3874284/blog/9914048
https://help.aliyun.com/zh/arms/alarm-operation-center/best-practices-for-notification-policies
[3]《一文详解阿里云可观测体系下标签最佳实践》
https://help.aliyun.com/zh/arms/alarm-operation-center/create-and-manage-notification-policies
https://help.aliyun.com/zh/arms/alarm-operation-center/use-k8s-labels-to-dispatch-alerts
https://help.aliyun.com/zh/arms/alarm-operation-center/use-alibaba-cloud-tags-to-dispatch-alerts
相关链接:
https://github.com/OuyangKevin/CloudAssistantTool/tree/main
https://help.aliyun.com/zh/arms/prometheus-monitoring/data-access-via-access-center
https://help.aliyun.com/zh/arms/alarm-operation-center/product-overview/alarm-management-overview