17.1.5 查询层:PromQL与HTTP API

查询层负责将时序数据转化为可用的指标与洞察,主要由 PromQL 与 HTTP API 组成。PromQL 用于交互式查询与规则计算,HTTP API 提供程序化访问,二者共同支撑告警、可视化与自动化运维。

原理草图(查询层在整体链路中的位置):

文章图片

PromQL 核心概念包括:指标类型(Counter/Gauge/Histogram/Summary)、时间序列(metric+label)、向量类型(Instant/Range)、标量与字符串。查询常见模式为:筛选(基于标签匹配)、聚合(sum/avg/max/min/count)、函数(rate/increase/irate/predict_linear)、时间窗口([5m] 等),以及基于标签的聚合维度(by/without)。

PromQL 示例(含命令解释):

# 实时负载(单实例)
node_load1

# 实时负载(多实例平均)
avg(node_load1) by (instance)

# 计算 QPS(1分钟窗口)
sum(rate(http_requests_total[1m])) by (service)

# 失败率(5xx 比例)
sum(rate(http_requests_total{code=~"5.."}[5m])) 
/ 
sum(rate(http_requests_total[5m]))

# CPU 利用率(1-空闲)
1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)

# 直方图分位(P95)
histogram_quantile(
  0.95,
  sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
)

HTTP API 主要用于自动化集成与数据获取。以下为完整可执行示例(含参数说明):

# 假设 Prometheus 监听在 9090
PROM_URL="http://127.0.0.1:9090"

# 即时查询
# query 参数为 PromQL 表达式
curl -s "${PROM_URL}/api/v1/query" \
  --data-urlencode 'query=sum(rate(http_requests_total[1m])) by (service)' | jq .

# 范围查询
# start/end 为 RFC3339 或 Unix 时间戳,step 为步长(秒)
curl -s "${PROM_URL}/api/v1/query_range" \
  --data-urlencode 'query=1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)' \
  --data-urlencode "start=$(date -u -d '-30 min' +%s)" \
  --data-urlencode "end=$(date -u +%s)" \
  --data-urlencode "step=30" | jq .

# 获取标签与指标元数据
curl -s "${PROM_URL}/api/v1/labels" | jq .
curl -s "${PROM_URL}/api/v1/label/instance/values" | jq .

# 获取目标与配置状态
curl -s "${PROM_URL}/api/v1/targets" | jq '.data.activeTargets[] | {job,instance,health,lastError}'
curl -s "${PROM_URL}/api/v1/status/config" | jq -r '.data.yaml'

最小依赖安装与工具准备(便于调试 API 输出):

# 安装 jq(用于解析 JSON)
# Debian/Ubuntu
sudo apt-get update && sudo apt-get install -y jq

# CentOS/RHEL
sudo yum install -y jq

排错与诊断(查询层常见问题):
- 查询无数据:检查是否存在目标、指标名是否正确、标签是否匹配
bash # 列出所有指标名 curl -s "${PROM_URL}/api/v1/label/__name__/values" | jq -r '.data[]' | head
- 结果过慢:缩小时间范围、增大 step、使用 recording rules 预计算
- Counter 未配 rate/increase:导致曲线跳变或不符合预期
- 高基数标签:造成查询慢与内存压力,避免使用 request_id/user_id 等

Recording Rules 示例(降低面板与告警开销):

# /etc/prometheus/rules/recording.yml
groups:
- name: recording_basic
  rules:
  - record: job:http_requests_total:rate5m
    expr: sum(rate(http_requests_total[5m])) by (job, service)

Prometheus 配置加载该规则文件:

# /etc/prometheus/prometheus.yml
rule_files:
  - /etc/prometheus/rules/recording.yml

命令解释:
- record 定义新序列名称
- expr 为预计算的 PromQL
- rule_files 用于加载规则文件

性能与实践要点:
- Counter 必须配合 rate/increase,Gauge 可直接使用或聚合
- 避免高基数标签带来查询与存储压力
- 合理选择窗口长度,短窗口敏感、长窗口平滑
- 面板与告警尽量基于 recording rules
- 统一封装查询模板,沉淀指标口径

练习:
1. 编写 PromQL 统计每个服务 5 分钟内的 5xx 失败率,并通过 API 拉取结果。
2. 以 1 小时范围、step=60s 做 CPU 利用率的范围查询,观察响应耗时。
3. 将 QPS 计算写成 recording rule,并在 /api/v1/query 中验证新序列存在。

本查询层内容是 Prometheus 可观测的核心入口,既要掌握 PromQL 表达与语义,也要掌握 API 接口与性能边界,才能在告警、可视化与自动化运维中稳定输出价值。