2. Prometheus 基础回顾:架构、数据模型与 PromQL 核心概念

在进入容量压测与巡检脚本编排之前,必须牢固掌握 Prometheus 的核心基础。本章将系统回顾 Prometheus 的拉取式架构、多维数据模型以及 PromQL 的查询本质,为后续的指标采集、告警规则编写和自动化巡检脚本奠定坚实的理论基础。

2.1 Prometheus 整体架构与核心组件

Prometheus 采用 拉取(Pull) 模式采集指标,区别于传统的推送(Push)模式。这种设计使其在服务发现、故障隔离和可靠性方面具有天然优势。其核心架构由以下组件构成:

Prometheus 核心架构组件与数据流 被监控目标 (Targets) /metrics 端点 Exporter / 应用 服务发现 k8s / consul / file DNS / 静态配置 Prometheus Server Retrieval (抓取) TSDB (存储) HTTP API / PromQL Alerting (告警) Alertmanager 去重 / 分组 静默 / 路由 可视化 Grafana Prometheus UI 客户端库 Pushgateway 架构要点说明: 1. 核心是 Pull 模式:Prometheus Server 主动从 Targets 的 /metrics 端点拉取数据。 2. 服务发现动态管理 Targets,无需手动重启配置。 3. 告警由 Server 生成,由 Alertmanager 统一处理;Pushgateway 用于短期任务指标推送。
容量压测视角: 在压测场景中,Pull 模式意味着压测工具(如 Locust、k6)需要暴露 /metrics 端点,Prometheus 才能抓取到实时并发数、QPS、错误率等关键指标。服务发现机制(如基于 Consul 或 Kubernetes)可以自动将压测节点纳入监控范围,无需手动维护目标列表。

2.2 数据模型:指标、标签与样本

Prometheus 的数据模型是其强大查询能力的基石。所有采集到的数据本质上都是一个带时间戳的 时间序列(Time Series),由以下核心元素唯一标识:

元素 定义 示例 说明
Metric Name 指标名称,描述被监控量的含义 http_requests_total 必须符合正则 [a-zA-Z_:][a-zA-Z0-9_:]*
Labels 键值对标签,用于维度区分 {method="GET", status="200"} 每个标签对构成一个维度,组合后唯一标识时间序列
Sample 实际数据点,包含值和时间戳 1024 @ 1700000000 值可以是任意 64 位浮点数;时间戳精确到毫秒

一个完整的时间序列在 Prometheus 内部表示为:

<metric_name>{<label_name1>="<label_value1>", ...}  <value>  [<timestamp>]

例如,一个记录 HTTP 请求总数的指标可能如下:

http_requests_total{method="POST", handler="/api/v1/order", instance="10.0.0.1:8080", job="order-service"}  2048  @ 1700000000

2.2.1 指标类型(Metric Types)

Prometheus 客户端库提供了四种核心指标类型,理解它们对于编写正确的巡检脚本至关重要:

类型 行为特征 典型用途 巡检脚本关注点
Counter 只增不减(重启归零) 请求总数、错误总数、CPU 时间 使用 rate() 或 increase() 计算速率
Gauge 可增可减,反映当前状态 内存使用量、并发连接数、温度 直接取值,或使用 avg_over_time() 平滑
Histogram 分桶统计,累积计数 请求延迟分布、响应大小分布 使用 histogram_quantile() 计算 P99/P95
Summary 客户端预计算的分位数 请求延迟分位数(无法聚合) 直接读取,但注意无法跨实例聚合
常见误区: 在巡检脚本中,对 Counter 类型直接使用 avg() 或 sum() 而不结合 rate() 是常见错误。Counter 的原始值是累积值,必须通过速率函数才能反映当前负载水平。例如,rate(http_requests_total[5m]) 才是正确的每秒请求速率。

2.3 PromQL 核心概念:查询与聚合

PromQL(Prometheus Query Language)是 Prometheus 的查询语言,也是我们编写巡检脚本和告警规则的核心工具。掌握 PromQL 的核心概念,意味着能够从海量时间序列中精确提取所需信息。

2.3.1 选择器与匹配模式

PromQL 通过 选择器 来匹配时间序列。选择器由指标名称和标签匹配器组成:

# 精确匹配
http_requests_total{job="api-server", method="GET"}

# 正则匹配
http_requests_total{instance=~"10.0.0.*"}

# 负向匹配
http_requests_total{status!~"5.."}

# 隐式匹配(省略标签)
http_requests_total  # 匹配所有该指标下的时间序列

2.3.2 范围向量与瞬时向量

这是 PromQL 中最容易混淆的概念,也是编写巡检脚本时必须清晰区分的:

向量类型 语法 含义 巡检脚本应用
Instant Vector metric_name{labels} 返回最新时间戳的一个样本值 获取当前 CPU 使用率、当前内存占用
Range Vector metric_name{labels}[5m] 返回过去一段时间窗口内的多个样本值 计算过去 5 分钟的平均延迟、速率

范围向量是计算速率、分位数和滑动窗口聚合的基础。例如:

# 计算过去 5 分钟内每秒请求速率
rate(http_requests_total[5m])

# 计算过去 10 分钟内 P99 延迟
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[10m]))

2.3.3 常用聚合与运算函数

在容量压测巡检脚本中,以下 PromQL 函数和操作符使用频率最高:

PromQL 核心函数分类与压测巡检应用 速率计算 rate() / irate() increase() 压测 QPS / 错误率 聚合操作 sum() / avg() / max() topk() / count() 按实例/接口聚合 分位数计算 histogram_quantile() quantile_over_time() P99 / P95 延迟 滑动窗口 avg_over_time() max_over_time() 基线/阈值平滑 巡检脚本 PromQL 使用原则: 1. 压测速率指标:优先使用 rate() 而非 irate(),后者对短时抖动敏感。 2. 聚合维度:按 job / instance / handler 聚合,避免丢失关键维度。 3. 时间窗口:巡检脚本中建议使用 5m 或 10m 窗口,平衡灵敏度与稳定性。

2.3.4 一个完整的巡检查询示例

假设我们需要编写一个巡检脚本,检查过去 5 分钟内所有 API 服务的错误率是否超过 1%。对应的 PromQL 查询如下:

# 步骤1:计算每秒错误请求数(Counter 速率)
sum(rate(http_requests_total{status=~"5.."}[5m])) by (job, instance)

# 步骤2:计算每秒总请求数
sum(rate(http_requests_total[5m])) by (job, instance)

# 步骤3:计算错误率(除法运算)
(
  sum(rate(http_requests_total{status=~"5.."}[5m])) by (job, instance)
)
/
(
  sum(rate(http_requests_total[5m])) by (job, instance)
)
* 100  # 转换为百分比
脚本编排提示: 在 Python 巡检脚本中,上述 PromQL 查询会通过 prometheus_api_client 或直接调用 HTTP API 执行。查询结果是一个包含 job 和 instance 标签的向量,脚本需要遍历结果并与阈值(如 1.0)进行比较,触发告警或记录日志。

2.4 本章小结

本章回顾了 Prometheus 的三大基础支柱:

  • 架构:Pull 模式、服务发现、TSDB 存储与告警链路,是理解数据采集流程的基础。
  • 数据模型:指标名称 + 标签 = 时间序列;Counter/Gauge/Histogram/Summary 四种类型决定了查询方式。
  • PromQL:瞬时向量 vs 范围向量、速率函数、聚合操作与分位数计算,是巡检脚本的核心语言。

这些概念将贯穿后续所有章节,尤其是在编写容量压测脚本和巡检规则时,每一个 PromQL 查询的正确性都直接决定了巡检结果的可靠性。