# 判定、恢复与状态变化

规则不是查到就报：评估周期、持续时长、恢复条件三个参数加一套状态机，决定事件何时首次触发、何时恢复、会不会抖动。

最后校对于 2026-10-10

一条规则不是「查到就报」。中间有三个时间参数和一套状态机， 它们决定了「什么时候第一次响」「什么时候不再响」「会不会来回抖」。

## 三个时间参数[​](#三个时间参数 "三个时间参数的直接链接")

| 参数     | 界面上叫                       | 含义                                   | 默认          |
| -------- | ------------------------------ | -------------------------------------- | ------------- |
| 执行频率 | 执行频率 / Execution frequency | 每隔多久跑一次查询                     | `@every 60s`  |
| 持续时长 | 持续时长 / For duration        | 条件要连续成立多久，才产生事件         | 60 秒         |
| 留观时长 | 留观时长 / Recover duration    | 条件不再成立后，还要观察多久才判定恢复 | 0（立即恢复） |

三个参数各自解决一个问题：

* **执行频率**决定发现问题的最快速度，也决定这条规则给数据源施加多大压力。 查一次要 10 秒的 SQL，就别设 15 秒的频率。它填的是 cron 表达式，`@every 60s` 是默认值。
* **持续时长**过滤毛刺。CPU 瞬间冲到 100% 又掉回来，不值得叫醒人； 持续 3 分钟就值得。
* **留观时长**过滤恢复侧的毛刺。指标在阈值上下反复横跳时， 没有留观就会「恢复—触发—恢复—触发」刷屏。 注意它拦住的是**恢复事件本身**，不只是恢复通知——窗口没熬过，事件就还是触发中的状态。

## 状态怎么走[​](#状态怎么走 "状态怎么走的直接链接")

```
   正常

    │  条件成立

    ▼

   待触发 ────── 条件持续了「持续时长」 ──────> 触发中（产生事件，发通知）

    │                                              │

    │ 条件不成立了                                  │ 条件不成立

    ▼                                              ▼

   回到正常                                      留观中

   （没产生过事件，不会有恢复通知）                  │ 熬过「留观时长」

                                                   ▼

                                                已恢复（发恢复通知）
```

关键点：**从「待触发」直接回到正常，是不会有任何通知的**， 因为压根没产生过事件。只有真的进入过「触发中」，后面才会有恢复通知。

恢复通知本身可以关掉（规则上的「恢复时通知」开关）。

## 自定义恢复条件[​](#自定义恢复条件 "自定义恢复条件的直接链接")

默认的恢复判定就是「触发条件不再成立」。有些场景想要不对称的阈值， 比如「超过 90% 才告警，但要掉到 70% 以下才算恢复」——这是防抖动的标准做法。

**开源版的 Prometheus 规则没有这个开关**，恢复永远是触发条件的反面， 想防抖只能靠留观时长。ElasticSearch、Loki、ClickHouse 这些走「触发条件」表单的类型 才有独立的恢复条件，而且默认值按类型不同：日志类默认是「查不到数据就恢复」。

## 一条规则可以有多个级别[​](#一条规则可以有多个级别 "一条规则可以有多个级别的直接链接")

规则的查询是一个列表，每条查询带自己的级别：

```
cpu_usage_active > 75   →  S3

cpu_usage_active > 85   →  S2

cpu_usage_active > 95   →  S1
```

配合「抑制」开关：同一个对象同时命中多条时，只保留最严重的那一条， 不会给你发三条消息。

## 想知道某次判定到底发生了什么[​](#想知道某次判定到底发生了什么 "想知道某次判定到底发生了什么的直接链接")

规则页上有**判定记录**：每个评估周期都留一条，记着这次查询返回了什么、 判定结果是什么、有没有被 Pipeline 丢掉、有没有被屏蔽。

「查询在即时查询页面有结果，但规则不触发」这类问题，答案基本都在这里。 见[判定记录](https://n9e.github.io/zh/docs/alerting/execution-records.md)。

## 相关[​](#相关 "相关的直接链接")

* [告警生命周期与级别](https://n9e.github.io/zh/docs/concepts/alert-lifecycle.md)
* [评估周期与恢复](https://n9e.github.io/zh/docs/alerting/evaluation.md)
* [告警为什么反复触发或从不恢复？](https://n9e.github.io/zh/docs/troubleshooting/alert-flapping.md)
