2. 使用PromQL查询基础指标
任务目标
本案例将使用PromQL查询Prometheus中采集的基础指标,重点获取节点CPU使用率与内存使用率,并理解Prometheus四种核心指标类型(Counter、Gauge、Histogram、Summary)在查询中的差异。
环境准备
假设已有一个运行中的Prometheus实例(默认端口9090),且通过node_exporter采集了目标节点指标。验证环境可用以下命令快速启动:
# 启动 node_exporter(默认端口9100)
./node_exporter &
# 启动 Prometheus,配置文件 prometheus.yml 中已添加该 job
./prometheus --config.file=prometheus.yml &
核心PromQL查询
以下查询可直接在Prometheus Web UI的Graph页面执行,或通过HTTP API /api/v1/query?query=... 调用。
1. CPU使用率(Gauge类型)
node_exporter暴露的CPU指标为Counter类型(node_cpu_seconds_total),需使用rate()函数计算每秒增长率后,再求使用率:
# 单核CPU使用率(按mode维度)
100 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100
# 所有CPU核平均使用率(推荐)
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
说明: mode="idle"表示空闲时间,用100%减去空闲率即为使用率。[5m]为时间窗口,表示最近5分钟的速率。
2. 内存使用率(Gauge类型)
内存指标直接为Gauge类型,无需rate计算:
# 内存使用率 = (总内存 - 可用内存) / 总内存 * 100
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
3. 综合查询:同时获取CPU与内存
# 使用向量匹配,一次返回两个指标
(
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
) / 100 as cpu_usage,
(
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))
) as mem_usage
该查询在Prometheus 2.30+版本中支持,返回包含cpu_usage和mem_usage标签的向量。
指标类型理解
| 类型 | 特征 | 典型查询方式 | 本案例示例 |
|---|---|---|---|
| Counter | 只增不减,重启归零 | rate()/increase() | node_cpu_seconds_total |
| Gauge | 可增可减,反映当前值 | 直接查询 | node_memory_MemAvailable_bytes |
| Histogram | 分位数统计,带_bucket后缀 | histogram_quantile() | http_request_duration_seconds |
| Summary | 客户端计算分位数,带_sum/_count | 直接查询分位数 | go_gc_duration_seconds |
验证方法
在Prometheus UI的Graph页面执行上述查询,观察以下结果即判定通过:
- CPU使用率查询返回0-100之间的数值,且与
top命令显示的%CPU大致吻合(误差在±10%以内); - 内存使用率查询返回0-1之间的小数(若未乘以100),乘以100后与
free -m计算的百分比一致; - 在Graph标签页切换到Table视图,能看到每个instance对应的具体数值;
- 执行
node_cpu_seconds_total直接查询,确认返回值为递增的Counter类型;执行node_memory_MemAvailable_bytes确认返回值为实时变化的Gauge类型。
常见问题
- 查询结果为空:检查Prometheus Targets页面确认node_exporter处于UP状态,且指标名拼写正确(可用
node_cpu_seconds_total搜索确认存在); - CPU使用率超过100%:多核机器上未除以CPU核数导致,使用
avg by (instance)聚合可避免; - 时间窗口过短:
[1m]可能因数据点不足导致无结果,建议使用[5m]或更长。