这将是一个系列,讲解 夜莺监控 的设计思考。你可以把它理解为:原理、最佳实践和产品设计时的折中取舍。
本系列其他文章:
本篇聊聊夜莺里跟机器相关的那些事:机器的数据采集、机器的归组打标签、机器元信息、机器告警分派等。
核心要点
- 机器在监控系统里是一个特殊对象:它既承载业务服务,又承载采集器 agent,因此不能完全按 Pod 或纯指标标签来理解。
- 夜莺在 Prometheus 标签体系之外,额外提供业务组、机器标签、机器列表、metadata、机器失联和时间偏移告警等能力。
- 机器业务组主要用于权限和操作边界;机器标签主要用于把维度信息附加到监控指标上。
- 这些机器能力依赖 Categraf:heartbeat 负责机器列表和 metadata,writer 负责指标数据写入。
- 对业务组范围内的机器做告警,推荐使用变量方式,而不是老版本的“仅在本业务组生效”过滤方式。
前言:为什么机器是一个特殊概念
机器这个概念,在监控系统里有比较特殊的场景,主要原因有两个。
第一,机器上的服务有时会混部,导致机器和业务程序之间的对应关系不好处理。这就是对待机器不能像对待 Pod 的原因。
第二,采集器 agent 通常部署在机器上,对机器的管理会影响采集器管理。很多新的可观测性厂商宣传的 Fleet 机制,本质上也侧重采集层面,因为 agent 最终还是要部署到机器上。
Zabbix、Open-Falcon 等系统对机器概念都有额外抽象建模。Prometheus 生态则完全忽略机器概念的特殊性,走向了另一个极端。
夜莺监控(Nightingale)站在二者中间:既想遵从 Prometheus 生态玩法,又想给机器场景做一些额外支持,所以看起来稍微有点拧巴。但产品是为业务场景服务的,机器这个场景就在那,不是想砍就能砍掉的。
夜莺体系里,对机器的相关支持比较零散,本文会逐块说明。
机器分类管理:业务组和标签
夜莺里有告警自愈功能,可以到机器上执行脚本,所以机器权限必须非常小心。
最简单的方式是每台机器直接绑定人和角色,但这样不方便管理。因此,夜莺给机器设计了业务组概念。机器可以归属业务组,业务组关联管理人员,这些人员可以对机器做操作。
业务组可能划分得很细,例如每个 Service 作为一个业务组。DBA/MySQL/Proxy 可以是一个业务组,DBA/MySQL/DataNode/Mall 可以是另一个业务组。同一台机器可能部署多个 Service,所以机器需要支持同时挂在多个业务组。
Prometheus 生态里,监控指标的各类维度信息都是通过标签描述的。但业务组不能直接作为普通 Prometheus 标签,因为 Prometheus 标签不允许同 Key 多 Value。于是,夜莺支持在机器列表页面给机器打标签,这些机器标签会自动附加到机器监控指标上。
所以,夜莺里机器归组提供了两个机制:
| 机制 | 主要用途 |
|---|---|
| 业务组 | 通常按 Service 颗粒度划分,主要和权限、操作边界相关 |
| 标签 | 把某些维度信息附加到监控指标上,便于查询、看图和告警过滤 |
这一切的前提,是使用 Categraf 作为采集器,并且把 Categraf 的 heartbeat 和 writer URL 都指向夜莺。
如果没有使用 Categraf,机器列表就是空的,机器归组、打标签等能力也用不了。这并不会影响你对时序库中的数据做告警和看图,只是机器相关体验会少很多。
Categraf 部署到所有待监控目标机器上,采集机器元信息、基础监控指标,并可执行脚本做告警自愈。
机器信息上报:heartbeat 和 metadata
如果使用 Categraf 作为采集器,夜莺机器列表里会自动出现机器:

如果发现内存、CPU、时间偏移等列是 Unknown,可能原因是:
- 没有使用 Categraf 采集器。
- Categraf 配置文件里的 heartbeat 没有开启,或没有指向夜莺。
机器标识可以点击。点击后会打开侧拉板,展示机器元信息:

还有一个常见问题:机器列表里能看到机器 CPU、内存等信息,但仪表盘是空的,为什么?
可能原因是:
- Categraf 配置文件里 writer 部分配置不对,没有指向夜莺。
- 如果 writer 配置正确,就需要查看 Categraf 日志继续定位。
可以这样理解:heartbeat 负责“机器活着、元信息是什么”,writer 负责“指标数据写到哪里”。二者作用不同。
机器告警:失联、集群失联和时间偏移
使用 Categraf 之后,除了能看到机器列表、机器元信息、机器分组和标签之外,还可以对机器做特殊告警规则配置。

告警规则里有专门的 Host 类型,提供三种机器相关的告警规则:
- 机器失联。
- 机器集群失联。
- 机器时间偏移。
需要注意,机器时间偏移不是机器和 NTP Server 之间的时间偏移,而是 Categraf 所在机器和夜莺服务端之间的时间偏移。如果使用了 n9e-edge 边缘模块,就是 Categraf 所在机器和 n9e-edge 所在机器之间的时间偏移。
机器时间偏移比较常用,机器失联也很常用。原因是 Categraf + Nightingale 的监控数据流向是典型 PUSH 模型,没有 Prometheus 中的 up 指标,所以需要额外机制判定机器是否失联。
如何对业务组内机器做告警
一个常见问题是:机器挂载了业务组,我想对某些业务组做告警判定,应该怎么配置?
在夜莺体系里,性能最好的方式是使用变量。配置方式如下:

上图中创建了一个 ident 变量,变量类型是 机器标识,机器范围是 Default Busi Group 和 DevOps 两个业务组下的机器。然后在 PromQL 中引用 ident 标签作为过滤条件。
如果你的监控指标里已经有标签可以很方便地做过滤,也可以直接使用标签。
变量模式还有另一个好处:可以用于特殊机器的阈值配置。例如 Default Busi Group 和 DevOps 两个业务组下的机器默认 CPU 阈值都是 80,但其中有 1 台机器平时负载就很高,需要把 CPU 阈值设置为 88。此时可以再加一个阈值变量,同时继续配置 变量筛选 条件:

这个配置方式稍微有点复杂,但问题场景本身就是复杂的。
老版本没有 启用变量 这个配置,只有 仅在本业务组生效。那个方式性能不好,原理是:先拿告警规则里的 PromQL 去查询时序库里所有满足条件的数据,可能查到很多机器都告警了,然后再根据机器归属关系过滤,只保留本业务组下机器的相关告警。
变量方式更推荐,因为它在查询阶段就把范围限制住了。
仪表盘只查看业务组下的机器
既然夜莺里维护了机器和业务组关系,那么在仪表盘里查看机器时,能否只查看当前业务组下的机器?可以。
可以导入内置的机器相关仪表盘(在 Linux 类别下),打开 机器常用指标 仪表盘。默认是查看所有机器,因为 ident 变量配置是:
label_values(system_uptime, ident)
如下图:

然后修改 ident 变量:

保存仪表盘并刷新,就会看到机器变量下拉框里只有当前业务组下的机器。如果仪表盘所属业务组下面没有机器,就看不了数据。
其他机器相关功能
开源版本中,跟机器相关的功能主要就是上面这些。商业版会有额外功能,例如:
- Categraf 的采集规则中心化管理和下发。
- 专门的网络设备管理里需要采集器探针管理,会和机器管理联动。
FAQ
不使用 Categraf,夜莺还能做告警吗?
可以。夜莺仍然可以对已有数据源做告警判定。但机器列表、机器 metadata、机器归组、机器标签、机器失联等能力依赖 Categraf。
业务组和标签有什么区别?
业务组主要服务权限和操作边界,例如谁能对哪些机器做操作。标签主要服务指标维度,让查询、看图和告警过滤更方便。
为什么机器失联不能直接用 Prometheus 的 up?
Categraf + Nightingale 是 PUSH 模型,不是 Prometheus 主动抓取 exporter 的 PULL 模型,因此没有天然的 up 指标。夜莺需要通过 heartbeat 和相关机制判断机器是否失联。
机器列表有数据但仪表盘没数据,应该先查什么?
先区分 heartbeat 和 writer。机器列表依赖 heartbeat,仪表盘指标依赖 writer。如果机器列表正常但仪表盘为空,优先检查 Categraf writer 是否正确指向夜莺,并查看 Categraf 日志。
总结
夜莺对机器的设计,是在 Prometheus 标签体系和传统主机监控模型之间做折中。
如果只看指标和告警,机器不是必需对象;但如果要做机器权限、告警自愈、机器失联、metadata、采集规则管理和业务组范围过滤,机器又绕不开。夜莺通过 Categraf heartbeat、writer、业务组、标签和变量机制,把这些能力拼成了一套相对完整的机器管理体验。