把看板复制一份的那一刻,它就分叉了
一句话总结
模板变量让你不必复制仪表板。副本必然会分叉,而分叉之后,没有人知道哪一份才是正确的。
为什么需要它
服务有十二个时,起初为每个服务建一份仪表板似乎很自然:先做好一份,再复制并修改查询中的服务名即可。
问题从下一次修改开始。如果决定把错误率面板的 5 分钟 rate 改为 1 分钟 rate,就必须修改十二处,而现实中往往只改了三四处。等第十三个服务出现时,根本没有人再为它创建仪表板。 这个服务在发生故障之前,对所有人都是不可见的。
变量从结构上消除了这个问题:仪表板只有一个,观察对象通过页面顶部的下拉菜单切换。
它如何工作
变量有多种类型,实际工作中最关键的是下面两种。
| 类型 | 值来自哪里 | 问题 |
|---|---|---|
custom |
由人手工维护列表 | 新增一个对象,当天就会过时 |
query |
从数据中读取 | 没有这个问题,应优先使用 |
在 Prometheus 数据源中,可以通过 label_values 读取。
label_values(http_requests_total, handler)
当前数据中实际存在的 handler 值会成为下拉选项。新增一个 handler,选项也会自动出现。
而且,仅声明变量不会产生任何效果。 面板查询必须真正用该变量缩小范围。
sum(rate(http_requests_total{handler="$handler"}[5m]))
$handler、${handler}、[[handler]] 三种写法都可以。如果变量允许多选(multi-value),就不能继续使用 =,而应改成 =~"$handler",因为 Grafana 会把多个值拼成 a|b|c 的形式。
常见误解
“加变量会变慢。” 通常正相反。用变量缩小范围后,需要读取的时间序列减少,查询反而更快。真正会变慢的是把拥有数千个值的标签做成变量;这并不是变量本身的问题,而是在提醒你:这个标签根本不适合用下拉菜单选择。
“变量名随便取。” 最好与标签名一致。如果 $svc 指向的是 job 标签,六个月后维护这份仪表板的人一定会困惑。
实际工作中真正重要的事
告警规则不能使用仪表板变量。 告警在仪表板之外、没有页面的情况下执行。由于没有下拉菜单替换 $handler,这串字符会原样发送给 Prometheus,查询也会因语法错误而失败。
因此,把面板查询迁移成告警时,必须展开所有变量。要监控特定 handler,就直接写入值;要观察全部对象,就删除变量条件。这就是为什么“从仪表板创建告警”不能只靠复制粘贴完成。