第4章:健康检查工具 - Prometheus
Prometheus 是我在生产环境里用得最多的监控系统。说实话,刚开始接触它的时候,我也被它的 Pull 模型、多维数据模型和 PromQL 搞得有点晕。但一旦上手,你会发现它的设计确实干净——不像传统监控那样什么都往里塞,而是专注做一件事:采集、存储、查询时序数据。
今天我就从三个角度带你把它吃透:架构、安装配置、指标采集。嗯,都是实战里绕不开的东西。
4.1 Prometheus 架构——Pull 模型到底好在哪
很多刚接触 Prometheus 的人会问:为什么不用 Push?我个人习惯的思路是这样:Pull 模型让监控系统主动去拉数据,而不是等着被推送。好处是什么?
- 可控性强:监控端决定拉谁、什么时候拉、拉多久,而不是被采集端打爆。
- 自我发现:结合服务发现,新加的服务自动进入采集列表,不用改配置。
- 故障隔离:如果目标挂了,Pull 超时失败,不会影响监控系统本身。
下面这张图我把核心组件和流程画了一下,你看着应该就清楚多了。
你可能注意到了,Prometheus Server 是中心。它定期从 Targets 拉取数据,数据格式是 Key-Value 的时间序列。Exporter 负责把系统指标(CPU、内存、磁盘等)转成 Prometheus 能懂的 /metrics 接口。应用自己也可以直接暴露指标。
4.2 安装配置——从零搭一个可用的 Prometheus
安装其实不复杂,但配置细节容易踩坑。我记得第一次搭的时候,因为防火墙没放开 9090 端口,折腾了半小时。咱们直接说主流方式:二进制安装和 Docker 部署。
4.2.1 二进制安装(Linux)
# 下载最新版本(以 2.45.0 为例)
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
tar -xzf prometheus-2.45.0.linux-amd64.tar.gz
cd prometheus-2.45.0.linux-amd64
# 创建数据目录
mkdir -p /data/prometheus
解压后直接就能用。但默认配置只是最简单的,我们需要写一个像样的 prometheus.yml。
global:
scrape_interval: 15s # 默认抓取间隔
evaluation_interval: 15s # 评估告警规则的间隔
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['192.168.1.100:9100']
启动命令:
./prometheus --config.file=prometheus.yml --storage.tsdb.path=/data/prometheus
启动后访问 http://localhost:9090,就能看到 Prometheus 的 Web UI。
--storage.tsdb.path 所在磁盘配好告警,或者用 --storage.tsdb.retention.time 控制保留时间,比如 30d。
4.2.2 Docker 部署
如果你跟我一样喜欢容器化,Docker 方式更简洁:
docker run -d \
--name prometheus \
-p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
嗯,这里要注意:挂载配置文件时,一定要用路径,而且文件权限要 644。我遇到过因为文件权限问题导致容器启动失败,日志显示 “permission denied”。
4.3 指标采集——把数据喂给 Prometheus
Prometheus 采集指标的核心思想是:每个 Target 暴露一个 HTTP 端点,返回 Prometheus 格式的文本数据。格式大概长这样:
# HELP node_cpu_seconds_total Total seconds for each CPU state
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 100345.67
node_cpu_seconds_total{cpu="0",mode="system"} 2056.34
# HELP node_memory_MemAvailable_bytes Memory information
# TYPE node_memory_MemAvailable_bytes gauge
node_memory_MemAvailable_bytes 8352342016
有三种常见的指标采集方式:
| 方式 | 场景 | 举例 |
|---|---|---|
| Exporter(官方/社区) | 监控系统组件(Node、MySQL、Nginx 等) | node_exporter、mysqld_exporter |
| 应用自身暴露 | 自研服务,嵌入 Prometheus 客户端库 | Java 用 micrometer,Go 用 promhttp |
| Pushgateway | 短生命周期任务(批处理、CronJob) | 批量作业结束后推送指标 |
我个人最常用的还是 Exporter 方式,尤其是 node_exporter——几乎覆盖了所有主机层的指标。配置好之后,Prometheus 自动采集,不需要手动操作。
采集配置里还可以加一些过滤和标签改写:
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['10.0.0.1:9100', '10.0.0.2:9100']
relabel_configs:
- source_labels: [__address__]
regex: '(.*):9100'
target_label: 'instance'
replacement: '$1'
这段配置的意思是把原始地址里的端口去掉,只保留 IP 作为 instance 标签。嗯,这样的好处是告警信息里看起来干净一些。
说到采集,还有一个容易忽略的点:拉取超时。如果目标响应慢,Prometheus 默认 10 秒超时,超时后跳过这次采集。我曾经遇到过 MySQL Exporter 在业务高峰期查询太慢,导致很多点丢失。解决方法是优化 Exporter 查询,或者在配置里增大 scrape_timeout(但不要超过 scrape_interval)。
metric_relabel_configs 过滤掉不需要的指标,采集压力立刻降下来。记住:不是所有指标都要拉,只保留你关心的。
指标采集之后,Prometheus 会把它们存储到本地 TSDB。每条时序数据由 metric name 和 labels 唯一标识。比如 node_cpu_seconds_total{cpu="0",mode="idle"},这是一个 counter 类型的指标,只增不减。查询时用 PromQL 做聚合,比如 rate(node_cpu_seconds_total[5m]) 就能算出 CPU 利用率。
好了,Prometheus 的核心套路你已经清楚了。下一步就是在你的测试环境里搭一套,试试采集几个 Exporter。嗯,动手才是最好的学习方式。