机器是 Infra 层面的重要对象,自身健康状况必须被监控,包括机器是否存活、时间偏移、CPU 使用率、内存使用率、磁盘使用率等。在 Prometheus 生态里,通常使用标签对机器分组,再用 PromQL 配置告警规则。
夜莺监控(Nightingale)也可以使用 Promql 对机器做规则配置,但对于机器存活监控有不同的设计。另外夜莺里有业务组的概念,是和标签类似的分组机制,也给机器监控带来了很多便利,使得机器普通指标的监控,也有一些新的设计,本文逐一介绍。
核心要点
- PUSH 模式下,采集端宕机时无法继续上报
up=0,因此机器存活监控不能照搬 Prometheus PULL 模式。 - 夜莺提供 Host 类型告警,由服务端根据心跳或监控数据上报情况判断机器是否不可达。
- 普通机器指标仍然可以用 PromQL 配置,例如 CPU、内存、磁盘和自定义指标。
- “仅在本业务组生效”依赖查询结果里的
ident标签,且新版夜莺里已不推荐作为首选方式。 - 更推荐用业务组变量约束 PromQL 范围,或在通知规则里根据机器归属灵活分派通知人。
三类机器告警方式对比
| 方式 | 适合场景 | 关键依赖 | 注意事项 |
|---|---|---|---|
| Host 类型告警 | 机器失联、时间偏移 | 夜莺服务端心跳或数据上报判断 | 适合 PUSH 模式下的存活监控 |
| PromQL + 业务组变量 | 各团队分别管理自己的机器指标规则 | 指标里有 ident 标签,变量维护准确 |
适合分散管理和特殊阈值 |
| 统一规则 + 通知规则分派 | 运维统一管理机器告警规则 | 告警事件里有机器归属信息 | 适合集中治理和统一通知策略 |
机器存活监控
我们推荐使用 Categraf 采集机器监控数据,Categraf 通过 Prometheus remote write 协议将数据上报到夜莺监控(Nightingale)。这种模式,在业内称为 PUSH 模式,Prometheus 生态里,对于机器监控是在机器上面安装 Node Exporter,然后 Prometheus 进程去拉取,这种模式称为 PULL 模式。
PULL 模式可以很容易感知机器的存活状态,如果 Prometheus 去拉取 Node Exporter 失败,就说明机器不可达了,可以通过 up 指标进行告警配置:
up{job="node-exporter"} == 0
但是在 PUSH 模式下,是没法有这么一个 up 指标的。细想一下,如果 Categraf 存活,可以上报 up=1,如果 Categraf 宕机了,自然没法上报任何指标,也就没法上报 up=0 了,这样就没法通过 up 指标来感知机器的存活状态了。
所以在夜莺监控(Nightingale)的告警规则里,专门提供了 Host 类型的告警规则:

原理是:服务端周期性判断机器是否有心跳或者是否有监控数据上报,如果有就认为是存活的,如果太久(告警规则里配置的时间)没有心跳或者监控数据上报,就认为机器不可达了,从而触发告警。
⚠️ Host 告警模式下,除了机器失联,还有一个时间偏移的告警方式。注意,机器时间偏移并非是机器和 NTP Server 之间的时间偏移,而是 Categraf 所在的机器和夜莺服务端的时间偏移,如果用了 n9e-edge 边缘模块,就是 Categraf 所在的机器和 n9e-edge 所在机器的时间偏移。
机器普通指标监控
这里说的普通指标监控,是通过 Prometheus 数据源配置 PromQL,对机器的 CPU、内存、磁盘等指标进行监控。当然,也可以对机器上报的自定义指标进行监控。只要指标里有机器的唯一标识,在夜莺里通常是 ident 标签,我们就可以把它称为机器指标监控。
使用标签过滤
这是 Prometheus 生态里最常见的方式了,通过标签过滤出某一类机器,然后进行告警规则配置。比如我只想对 env="prod" 的机器做 CPU 使用率告警:
cpu_usage_active{env="prod"} > 90
除了 env="prod" 的机器,其他机器的 CPU 使用率超过 80% 就告警,那就要配置另外一条规则:
cpu_usage_active{env!="prod"} > 80
但如果有些指标里没有 env 标签,那就尴尬了,上面两个规则都无法命中这些没有 env 标签的机器。
仅在本业务组生效

原理:拿着告警规则里的 promql 去查询时序库里的所有满足条件的数据,可能查到很多机器都告警了,然后再根据机器的归属关系做过滤,只保留自己业务组下的机器的相关告警。
如果 Promql 查到的数据中没有 ident 标签(在夜莺里 ident 标签表示机器的唯一标识),那就歇菜了,此时就不管「仅在本业务组生效」这个配置了,直接报出来。只有 Promql 查到的数据里有 ident 标签,才会进行业务组过滤。
如果有 10 个业务组,每个下面都有机器相关的告警规则,并且都勾选了「仅在本业务组生效」,可以想象性能是不太好的,因为每个规则都要查询 TSDB 里的所有数据,然后再做业务组过滤。
「仅在本业务组生效」这种方式在新版夜莺里已经不推荐使用了。原因是它容易产生额外查询和过滤成本,也容易因为查询结果缺少 ident 标签而失效。
使用业务组变量
比如我配置了一个告警规则,只想对 Default Busi Group 和 DevOps 这俩业务组下面的机器生效,那我可以这么配置:

上图中,创建了一个 ident 变量,变量类型是 机器标识,机器范围是 Default Busi Group 和 DevOps 两个业务组下的机器。然后在 promql 中引用了 ident 标签作为过滤条件。
上例用的变量模式,还有另一个好处,是用于特殊机器的阈值配置,比如 Default Busi Group 和 DevOps 两个业务组下的机器默认 CPU 阈值都是 80,但是其中有1台机器很特殊,平时负载就很高,CPU 阈值要设置为 88,那就可以再加一个阈值变量,同时继续配置 变量筛选 条件:

这个配置方式稍微有点复杂,不过没办法,问题场景本身就是复杂的。
这种方式适合各个团队分散管理的模式。大家分别配置自己的告警规则,相互之间互不影响。对于需要给少量特殊机器设置特殊阈值的场景,也可以通过变量继续细分。
但有些公司的运维是统一管理机器相关告警规则,此时更推荐下面即将介绍的方式。
在通知规则里灵活分配通知人
对于某个指标,我们使用 Promql 配置告警规则,查询所有异常的机器,触发告警事件,然后这些事件交给某个通知规则,在通知规则里,再根据机器的归属关系,灵活分配通知人。

上例中配置了一个通知规则,这个通知规则是发送的阿里云电话,针对特定的业务组的机器生效,利用「机器业务组」这个属性做的过滤。上例中,如果发现告警事件里有 ident 标签,即机器信息,而且发现机器所属的业务组是 DBA-MySQL、DBA-Oracle、DBA-Postgres 之一,就会发送给对应的通知人。
当然,如果接告警的人是不同的团队,这里的配置会比较复杂。后面我们会继续优化,让订阅规则也支持根据机器所属业务组过滤和分配,届时管理起来会更方便一些。
配置建议
- 存活类问题优先使用 Host 类型告警,不要在 PUSH 模式下强行依赖
up指标。 - 普通指标告警要确认查询结果中包含
ident标签,否则业务组过滤和机器归属分派都可能失效。 - 多团队分散管理时,用业务组变量约束 PromQL 查询范围,避免互相影响。
- 集中运维管理时,可以先做统一指标规则,再在通知规则里按机器业务组分派通知人。
- 对特殊机器设置特殊阈值时,优先用变量表达差异,不要复制大量相似规则。
结语
夜莺监控(Nightingale)里的机器告警配置,核心不是“哪一种方式最好”,而是先区分存活告警和普通指标告警,再根据组织管理模式选择规则归属方式。
如果是 PUSH 模式下的机器失联,优先使用 Host 类型告警;如果是 CPU、内存、磁盘等普通指标,则根据团队分工选择业务组变量或通知规则分派。只要 ident 标签、业务组归属和通知策略设计清楚,机器告警就不会因为规则重复、归属不清或通知错配而失控。
FAQ
Q1:为什么 PUSH 模式下没有天然的 up=0?
A:因为采集端宕机后无法继续上报任何数据,也就无法主动上报 up=0。夜莺 Host 告警通过服务端判断心跳或数据上报间隔来解决这个问题。
Q2:机器普通指标告警一定要有 ident 标签吗?
A:如果要结合夜莺机器归属、业务组过滤或通知分派,查询结果里最好有 ident 标签。没有这个标签时,系统无法可靠判断告警属于哪台机器。
Q3:新版夜莺为什么不推荐“仅在本业务组生效”? A:这种方式需要先查询所有满足条件的数据,再按业务组过滤。业务组和规则数量变多后,性能和可理解性都不理想,因此更推荐变量或通知规则分派。