3. PromQL 入门与实践:基础语法、选择器、操作符与常用函数
PromQL(Prometheus Query Language)是 Prometheus 内置的数据查询语言,也是告警规则与自愈剧本的数据基石。在 Ansible 自愈场景中,PromQL 负责回答“当前系统状态是否异常”,而 Ansible 负责执行“如何修复异常”。本章将系统讲解 PromQL 的核心语法、选择器、操作符以及生产环境最常用的四个函数。
3.1 PromQL 基础语法与数据类型
PromQL 表达式求值后返回以下四种数据类型之一:
| 数据类型 | 说明 | 示例 |
|---|---|---|
| 瞬时向量 (Instant Vector) | 一组时间序列,每个序列包含一个最新采样值 | node_cpu_seconds_total |
| 区间向量 (Range Vector) | 一组时间序列,每个序列包含一段时间范围内的多个采样值 | node_cpu_seconds_total[5m] |
| 标量 (Scalar) | 一个简单的数字浮点值 | 3.14 |
| 字符串 (String) | 一个简单的字符串值(目前仅用于某些函数) | "critical" |
实践要点:告警规则和 Ansible 自愈触发条件几乎全部基于瞬时向量。区间向量主要用于
rate、increase 等聚合函数内部计算,不直接作为告警条件输出。
3.2 选择器:精准定位监控指标
选择器用于从 Prometheus 时间序列数据库中筛选出目标指标。根据返回类型分为瞬时向量选择器和区间向量选择器。
3.2.1 瞬时向量选择器
语法:<metric_name>{<label_match>}
- 精确匹配:
=例:node_memory_MemAvailable_bytes{instance="web-01"} - 正则匹配:
=~例:node_memory_MemAvailable_bytes{instance=~"web-.*"} - 反向匹配:
!=例:node_memory_MemAvailable_bytes{instance!="web-01"} - 反向正则:
!~例:node_memory_MemAvailable_bytes{instance!~"db-.*"}
3.2.2 区间向量选择器
在指标名或选择器后附加 [<duration>],返回过去一段时间内的所有样本。
# 过去 5 分钟所有 web 节点的 CPU 使用率原始数据
node_cpu_seconds_total{instance=~"web-.*",mode="idle"}[5m]
常见误区:区间向量不能直接用于算术运算或告警条件判断。必须先通过
rate、increase、avg_over_time 等函数将其转换为瞬时向量。
3.3 操作符:连接与计算
PromQL 支持四类操作符,用于构建复杂的告警表达式。
| 操作符类别 | 符号 | 典型用途 |
|---|---|---|
| 算术 | + - * / % ^ | 计算 CPU 使用率、内存使用百分比 |
| 比较 | == != > < >= <= | 触发告警阈值判断 |
| 逻辑/集合 | and or unless | 组合多个告警条件 |
| 向量匹配 | on ignoring group_left group_right | 多指标关联计算(如 CPU 使用率 = 1 - idle/total) |
3.3.1 向量匹配示例:计算 CPU 使用率
# 计算每个实例的 CPU 使用率(非 idle 时间占比)
(1 - avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))
/ avg by(instance)(rate(node_cpu_seconds_total[5m]))) * 100
自愈场景提示:当 CPU 使用率 > 90% 持续 5 分钟时,Ansible 可以触发自动扩容或重启异常进程。比较操作符
> 是告警规则的核心。
3.4 常用函数:rate, increase, histogram_quantile
以下四个函数是告警规则和自愈剧本中使用频率最高的 PromQL 函数。
3.4.1 rate() — 计算每秒平均增长率
适用于 Counter 类型指标(如请求总数、CPU 时间片总数)。计算区间向量在指定时间窗口内的每秒平均增长率。
# 过去 5 分钟,每个实例每秒 HTTP 请求数
rate(http_requests_total[5m])
# 过去 5 分钟,每个实例每秒 CPU 非 idle 时间
rate(node_cpu_seconds_total{mode!="idle"}[5m])
3.4.2 increase() — 计算区间内的增量
与 rate 类似,但返回的是整个时间窗口内的增量,而非每秒速率。
# 过去 1 小时内,每个实例的 HTTP 请求总数增量
increase(http_requests_total[1h])
# 过去 5 分钟内,每个实例接收的字节数增量
increase(node_network_receive_bytes_total[5m])
选择建议:告警规则中优先使用
rate(速率更直观,阈值不随窗口大小变化);容量规划或计费场景使用 increase(总量更易理解)。
3.4.3 histogram_quantile() — 计算分位数
适用于 Histogram 类型指标(如请求延迟、响应大小分布)。根据累积直方图计算指定分位数(0 ≤ φ ≤ 1)。
# 过去 5 分钟,每个实例的 P99 请求延迟(单位:秒)
histogram_quantile(0.99,
rate(http_request_duration_seconds_bucket[5m])
)
# 过去 5 分钟,每个实例的 P50 请求延迟
histogram_quantile(0.50,
rate(http_request_duration_seconds_bucket[5m])
)
重要限制:
histogram_quantile 必须在 rate 或 increase 之后计算,且输入必须是 _bucket 后缀的累积直方图指标。分位数计算对样本数量敏感,样本太少时结果可能不准确。
3.5 PromQL 核心函数与选择器关系图
3.6 综合实践:构建一条自愈告警表达式
以下示例展示如何将 PromQL 选择器、操作符和函数组合成一条可用于 Ansible 自愈的告警规则。
# 场景:当 web 节点 P99 延迟 > 2s 且持续 5 分钟时触发告警
# 表达式分解:
# 1. 选择 web 实例的延迟直方图
# 2. 计算过去 5 分钟的每秒 bucket 增长率
# 3. 计算 P99 分位数
# 4. 与阈值 2 比较
- alert: WebP99High
expr: |
histogram_quantile(0.99,
rate(http_request_duration_seconds_bucket{job="web"}[5m])
) > 2
for: 5m
labels:
severity: critical
annotations:
summary: "Web 服务 P99 延迟超过 2s (当前值: {{ $value | humanizeDuration }})"
Ansible 自愈联动:当 Prometheus 触发
1. 重启异常节点的 Nginx/应用进程
2. 如果 2 分钟内未恢复,则从负载均衡摘除该节点
3. 通知值班工程师介入
WebP99High 告警后,Ansible Tower/AWX 通过 webhook 接收告警,自动执行以下剧本:1. 重启异常节点的 Nginx/应用进程
2. 如果 2 分钟内未恢复,则从负载均衡摘除该节点
3. 通知值班工程师介入
3.7 本章小结
- 选择器是 PromQL 的入口,掌握
=、=~、!=、!~四种匹配模式即可覆盖 95% 场景。 - 区间向量必须配合
rate、increase等函数使用,不能直接参与告警条件判断。 - rate 用于计算每秒速率,increase 用于计算增量,histogram_quantile 用于计算延迟/响应大小分位数。
- 告警规则中的
for字段与 PromQL 中的时间窗口[5m]是两个独立概念:前者是告警持续多久才触发,后者是计算数据的时间范围。