作者:没有四次元口袋的蓝胖
日期:2026-09-30
标签:Prometheus, 监控体系
Prometheus+Grafana知识梳理(1)
监控系统是后端架构中不可或缺的一环。在微服务时代,没有监控就等于裸奔------服务挂了不知道、性能瓶颈找不到、容量规划靠猜。Prometheus 是目前最主流的开源监控方案,几乎所有中大型公司都在用,也是 Kubernetes 生态的标配监控组件。
这篇笔记聚焦 Prometheus 本身的架构设计与数据采集能力,从 Pull 模型的设计哲学到时序数据模型,再到 node_exporter 采集器的安装配置和常用 PromQL 指标,帮你建立扎实的基础认知。
核心掌握:Prometheus Pull模型与时序数据库、四大核心组件的职责分工、数据模型与四种指标类型、node_exporter采集与常用PromQL查询。
一、Prometheus核心架构
1.1 什么是Prometheus
Prometheus 是一个开源的系统监控和告警工具包,最初由 SoundCloud 于 2012 年开发,2016 年加入 CNCF(云原生计算基金会),是 Kubernetes 生态的标配监控组件。
核心特点:
- 多维数据模型:基于 metric name + key/value labels 组织时序数据
- Pull 模型:主动从目标拉取指标数据(也支持 Push 场景)
- 服务发现:自动发现监控目标(K8s、Consul、DNS 等)
- 强大的查询语言 PromQL:支持丰富的聚合、计算和过滤
1.2 Pull模型 vs Push模型
这是面试高频考点。Prometheus 的核心设计哲学是 Pull(拉取) 模型。
┌─────────────┐ HTTP GET /metrics ┌─────────────┐
│ Prometheus │ ◄──────────────────────────────── │ 目标服务 │
│ Server │ 定期拉取指标数据(默认15s) │ (Exporter) │
└─────────────┘ └─────────────┘
Pull模型的工作流程:
1. Prometheus Server 定时(scrape_interval)向目标发送 HTTP GET 请求
2. 目标暴露一个 /metrics 端点,返回纯文本格式的指标数据
3. Prometheus 解析并存储到时序数据库(TSDB)中
Pull vs Push 对比:
| 维度 | Pull模型(Prometheus) | Push模型(传统监控) |
|---|---|---|
| 数据流向 | 监控中心主动拉取 | 被监控端主动推送 |
| 目标存活感知 | 拉不到 = 目标挂了,天然感知 | 需要额外心跳机制 |
| 配置管理 | 集中在监控端配置 | 分散在各业务端配置 |
| 网络要求 | 监控端需要能访问目标 | 目标需要能访问监控端 |
| 适用场景 | 基础设施监控、微服务 | 定时任务、批处理作业 |
为什么选 Pull 而不是 Push? 这个设计决策背后有几个关键思考:
- 天然存活感知:Pull 不到数据就意味着目标挂了,不需要额外的心跳机制。
- 配置集中:所有采集目标配置在 Prometheus Server 端管理,不用分散到各个业务服务。
- 便于调试 :开发者可以直接
curl http://target:port/metrics查看原始指标,排查问题方便。 - 服务发现友好:配合 Consul、K8s 等服务发现机制,新实例上线自动纳入监控。
1.3 核心组件
Prometheus 生态由多个组件协作构成完整的监控体系:
┌──────────────────┐
│ Prometheus │
│ Server │◄── 拉取指标
│ (存储+查询+告警) │
└────────┬─────────┘
│
┌────────────┼────────────┐
│ │ │
┌─────▼─────┐ ┌──▼──────┐ ┌───▼────────┐
│ TSDB │ │Alertman │ │ Grafana │
│ (时序数据库)│ │ ager │ │ (可视化) │
└───────────┘ └────┬────┘ └────────────┘
│
┌────▼────┐
│ 邮件/钉钉 │
│ /微信等 │
└─────────┘
| 组件 | 职责 | 说明 |
|---|---|---|
| Prometheus Server | 数据拉取、存储、查询 | 核心组件,包含 TSDB 和 PromQL 引擎 |
| Exporter | 暴露指标数据 | 各种类型的指标采集器(node_exporter、mysql_exporter 等) |
| Pushgateway | 接收短生命周期任务的推送 | 定时任务等不适合 Pull 的场景 |
| Alertmanager | 告警处理与通知 | 去重、分组、静默、路由到不同通知渠道 |
| Grafana | 可视化展示 | Dashboard 面板、数据探索 |
各组件的关系:
- Prometheus Server 是整个体系的核心,负责定时从各 Exporter 拉取数据,存储到本地时序数据库(TSDB),同时支持 PromQL 查询引擎和告警规则评估。
- Exporter 是各类指标采集器,它们暴露 HTTP
/metrics端点,等待 Prometheus 来拉取。 - Pushgateway 是一个特殊组件,用于接收短生命周期任务(如 CronJob)主动推送的指标。这类任务可能在 Prometheus 来 Pull 之前就执行结束了,所以需要主动 Push。
- Alertmanager 接收 Prometheus 评估告警规则后发来的告警,负责去重、分组、静默、抑制,最终路由到邮件/钉钉/微信等通知渠道。
- Grafana 是纯可视化层,从 Prometheus 读取数据进行展示,本身不存储数据。
二、数据模型
2.1 时序数据格式
Prometheus 的数据模型非常简洁:每一条时序数据 = metric name + labels + timestamp + value。
# 数据格式示例
http_requests_total{method="GET", handler="/api/users", status="200"} 1027
http_requests_total{method="POST", handler="/api/users", status="201"} 83
# 拆解:
# metric name: http_requests_total
# labels: method="GET", handler="/api/users", status="200"
# timestamp: (Prometheus自动添加)
# value: 1027
- metric name :指标名称,描述"监控什么",如
http_requests_total、node_cpu_seconds_total。 - labels :键值对标签,用于区分同一指标的不同维度,如
method="GET"区分请求方法。 - timestamp:Prometheus 自动添加的采集时间戳,不需要手动指定。
- value:指标值,一个 64 位浮点数。
这种设计的好处是:通过 labels 的组合,可以在同一个指标下表达非常丰富的维度信息,查询时用 PromQL 按 labels 过滤和聚合。
2.2 四种核心指标类型
| 类型 | 说明 | 典型场景 |
|---|---|---|
| Counter | 只增不减的计数器 | 请求总数、错误总数 |
| Gauge | 可增可减的仪表盘 | CPU使用率、内存使用量、队列长度 |
| Histogram | 直方图,预定义桶分布 | 请求延迟分布、响应大小分布 |
| Summary | 摘要,客户端计算分位数 | 请求延迟的 P99/P95 |
yaml
# Counter示例:累计请求数(只能增加或重置为0)
http_requests_total{method="GET"} 5000
# Gauge示例:当前内存使用(可增可减)
node_memory_MemAvailable_bytes 8589934592
# Histogram示例:请求延迟分布
http_request_duration_seconds_bucket{le="0.1"} 2400
http_request_duration_seconds_bucket{le="0.5"} 4800
http_request_duration_seconds_bucket{le="1.0"} 4950
http_request_duration_seconds_bucket{le="+Inf"} 5000
http_request_duration_seconds_sum 1200.5
http_request_duration_seconds_count 5000
四种类型的选型建议:
- Counter :任何"累计量"场景。注意 Counter 只能增加(除非进程重启归零),不能直接读值,需要用
rate()计算增长率。 - Gauge:任何"当前值"场景。如温度、内存使用量、队列长度等,可以直接读取当前值。
- Histogram:需要知道分布的场景,如请求延迟。桶(bucket)的划分在服务端定义,多个实例的数据可以在 Prometheus Server 端聚合。
- Summary:对单实例的分位数精度要求极高时使用。分位数在客户端计算,精度更高但无法跨实例聚合。
三、node_exporter采集与常用指标
3.1 什么是node_exporter
node_exporter 是 Prometheus 官方提供的硬件和操作系统指标采集器,用于采集 Linux/Unix 服务器的 CPU、内存、磁盘、网络等基础指标。它是监控体系中最基础的一环------先监控主机,再监控应用。
3.2 安装与配置
二进制安装(了解即可)
bash
# 下载
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzvf node_exporter-1.8.2.linux-amd64.tar.gz
cd node_exporter-1.8.2.linux-amd64
# 启动(默认监听 9100 端口)
./node_exporter
# 验证:访问 http://localhost:9100/metrics 即可看到指标数据
Docker安装(推荐)
yaml
# docker-compose.yml 片段
services:
node_exporter:
image: prom/node-exporter:latest
container_name: node_exporter
ports:
- "9100:9100"
# 关键:挂载宿主机文件系统,才能采集宿主机指标
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|container)($$|/)'
restart: unless-stopped
要点 :Docker 安装时,必须将宿主机的 /proc、/sys、/ 以只读方式挂载到容器内,并通过 --path.* 参数指定路径。否则 node_exporter 采集到的是容器自身的指标,而不是宿主机。
3.3 配置Prometheus采集
在 prometheus.yml 中添加采集任务(scrape job):
yaml
global:
scrape_interval: 15s # 全局默认采集间隔
scrape_configs:
# 采集 Prometheus 自身指标
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# 采集 node_exporter
- job_name: 'node'
static_configs:
- targets: ['node_exporter:9100'] # Docker环境用容器名
labels:
env: 'production' # 自定义标签
instance: 'web-server-01'
3.4 常用指标速查
面试和实际工作中最高频的 PromQL 查询,按场景分类:
CPU相关
promql
# CPU使用率(百分比)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 各模式CPU时间占比
rate(node_cpu_seconds_total[5m])
# CPU核心数
count(node_cpu_seconds_total{mode="idle"}) by (instance)
解读 :CPU 使用率的核心思路是 100% - idle%。node_cpu_seconds_total 是 Counter 类型,记录了各模式(user、system、idle、iowait 等)下的 CPU 秒数。用 rate() 计算每秒增长率,取 mode="idle" 的空闲占比,再用 100 减去就是使用率。
内存相关
promql
# 内存使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# 可用内存
node_memory_MemAvailable_bytes
# 已用内存(不含buffer/cache)
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes
# Swap使用率
(1 - node_memory_SwapFree_bytes / node_memory_SwapTotal_bytes) * 100
解读 :注意用 MemAvailable 而不是 MemFree。MemAvailable 包含了可回收的 buffer/cache 空间,更能反映实际可用内存。MemFree 只是完全空闲的内存,Linux 会把大量内存用于缓存,所以 MemFree 通常很小,直接用会导致误报。
磁盘相关
promql
# 磁盘使用率
(1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) * 100
# 磁盘IO速率(读)
rate(node_disk_read_bytes_total[5m])
# 磁盘IO速率(写)
rate(node_disk_written_bytes_total[5m])
# inode使用率
(1 - node_filesystem_files_free / node_filesystem_files) * 100
解读 :磁盘使用率用 avail 而不是 free。avail 包含可回收的空间(如 reserved for root),free 是完全空闲的。监控用 avail 更准确。fstype!~"tmpfs|overlay" 过滤掉临时文件系统,只关注真实磁盘。
网络相关
promql
# 网络接收速率(bytes/s)
rate(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*"}[5m])
# 网络发送速率(bytes/s)
rate(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*"}[5m])
# 网络错误率
rate(node_network_receive_errs_total[5m])
解读 :device!~"lo|veth.*|docker.*" 过滤掉 loopback、虚拟网卡和 Docker 网桥,只关注真实物理网卡。
四、PromQL关键函数速记
PromQL 是 Prometheus 的查询语言,以下是数据采集场景中最常用的函数:
| 函数 | 作用 | 适用类型 | 说明 |
|---|---|---|---|
rate() |
每秒平均增长率 | Counter | 取时间窗口内所有点做线性回归,平滑 |
irate() |
瞬时增长率 | Counter | 只取最后两个数据点,对突变更敏感 |
increase() |
时间段内的增量 | Counter | 等价于 rate() * 时间窗口秒数 |
histogram_quantile() |
分位数计算 | Histogram | 如 histogram_quantile(0.99, ...) 算 P99 |
avg by() / sum by() |
聚合运算 | 通用 | 按指定 label 分组聚合 |
rate() vs irate():
irate()只取最后两个数据点,对突变更敏感,适合实时面板展示。rate()取时间窗口内所有点做线性回归,更平滑,适合告警规则。- 告警用
rate(),实时面板可以用irate()。
五、常见面试注意点
- Pull模型的优势:天然感知目标存活、配置集中、易于调试(直接 curl /metrics 查看)。
- Push模型的使用场景:短生命周期的批处理任务(如 CronJob),这类任务可能还没等到 Pull 就结束了,需要主动 Push 到 Pushgateway。
- Counter vs Gauge :Counter 只能用
rate()/increase()计算速率;Gauge 可以直接读取当前值。 - Histogram vs Summary:Histogram 在服务端聚合,适合多实例;Summary 的分位数在客户端计算,无法跨实例聚合。
🗺️ 思维导图速览
Prometheus 架构与数据采集
├── Pull模型
│ ├── 工作流程:定时HTTP GET → /metrics → 解析存储
│ ├── 优势:存活感知、配置集中、便于调试
│ └── Push场景:短生命周期任务 → Pushgateway
│
├── 核心组件
│ ├── Prometheus Server:拉取+存储+查询+告警
│ ├── Exporter:暴露指标(node/mysql/redis exporter)
│ ├── Pushgateway:接收短任务推送
│ ├── Alertmanager:告警处理与通知(见后续文章)
│ └── Grafana:可视化展示(见后续文章)
│
├── 数据模型
│ ├── 格式:metric_name{labels} value
│ ├── Counter:只增不减 → rate()/increase()
│ ├── Gauge:可增可减 → 直接读值
│ ├── Histogram:桶分布 → 服务端聚合
│ └── Summary:客户端分位数 → 无法跨实例聚合
│
├── node_exporter
│ ├── 安装:二进制 / Docker(挂载 /proc /sys /)
│ ├── 配置:prometheus.yml 添加 scrape_configs
│ └── 常用指标
│ ├── CPU:100 - idle% → rate()
│ ├── 内存:1 - avail/total
│ ├── 磁盘:1 - avail/size → 过滤tmpfs
│ └── 网络:rate(receive/transmit_bytes_total)
│
└── PromQL关键函数
├── rate():平滑增长率(告警推荐)
├── irate():瞬时增长率(面板推荐)
├── increase():时间段增量
└── histogram_quantile():分位数
📝 写在最后
学习建议
- 理解 Pull 模型的设计哲学:为什么选 Pull 而不是 Push?这个设计决策背后的思考(服务发现、配置集中、存活感知)是面试常考的架构设计题。
- 熟悉四种指标类型:Counter/Gauge/Histogram/Summary 各自适用什么场景、怎么查询,这是基础知识中的基础。
- 动手写 PromQL:把上面的 CPU、内存、磁盘、网络 PromQL 在 Prometheus UI 里敲一遍,看看返回结果。纸上得来终觉浅。
- 搞清楚
rate()和irate()的区别:这在面试和实际工作中都非常高频。
面试高频问题速答
Q:Prometheus 的 Pull 模型和 Push 模型有什么区别?
Pull 模型:Prometheus Server 定时主动拉取目标的 /metrics 端点数据。优势是天然感知目标存活(拉不到就是挂了)、配置集中、便于调试。Push 模型:目标主动推送数据到 Pushgateway,适用于短生命周期的批处理任务(如 CronJob),这类任务可能在 Pull 之前就执行完了。
Q:Counter 和 Gauge 有什么区别?
Counter 是只增不减的计数器(如请求总数),只能通过
rate()或increase()计算变化率。Gauge 是可增可减的仪表盘(如 CPU 使用率),可以直接读取当前值。
Q:Histogram 和 Summary 有什么区别?
Histogram 在服务端维护预定义桶(bucket)的计数器,多个实例的数据可以在 Prometheus Server 端聚合,适合多副本场景。Summary 在客户端直接计算分位数(如 P99),精度更高但无法跨实例聚合。一般推荐用 Histogram。