跳转至

585_Prometheus监控系统

一句话概述:Prometheus 是 CNCF 毕业的开源监控系统,通过拉取模式采集时序指标数据,配合 PromQL 查询语言和 Alertmanager 告警,是云原生监控的事实标准。

核心知识点表

概念白话解释
时序数据带时间戳的数据点,如"14:00 CPU=80%,14:01 CPU=82%"
Pull 模式Prometheus 主动去"拉"数据,而不是等服务推送
Exporter导出器,把应用的指标转成 Prometheus 能读的格式
PromQLPrometheus 查询语言,用来查询和计算指标
Scrape抓取,Prometheus 定期去目标端点采集指标
Alertmanager告警管理器,处理通知的发送、分组、静默
Label标签,给指标加维度(如 instance="server1")

安装配置

Docker 快速启动

# 最简方式启动 Prometheus
docker run -d \
  --name prometheus \                   # 容器名
  -p 9090:9090 \                        # Web 界面端口
  -v ./prometheus.yml:/etc/prometheus/prometheus.yml \  # 配置文件
  prom/prometheus:latest                # 最新版(v3.x,2026)

配置文件(prometheus.yml)

# prometheus.yml — Prometheus 核心配置
global:
  scrape_interval: 15s                  # 每 15 秒采集一次(全局默认)
  evaluation_interval: 15s              # 每 15 秒评估一次告警规则

# 告警规则文件
rule_files:
  - "alert_rules.yml"                   # 引用告警规则

# 采集目标配置
scrape_configs:
  # 监控 Prometheus 自身
  - job_name: "prometheus"              # 任务名
    static_configs:
      - targets: ["localhost:9090"]     # 采集目标

  # 监控服务器(通过 Node Exporter)
  - job_name: "node"
    static_configs:
      - targets:                        # 多个目标
          - "node-exporter:9100"        # 服务器1
          - "192.168.1.102:9100"        # 服务器2
        labels:
          group: "production"           # 自定义标签

  # 监控应用
  - job_name: "myapp"
    metrics_path: "/metrics"            # 指标端点路径
    static_configs:
      - targets: ["myapp:8080"]

Docker Compose 完整部署

# docker-compose.yml
services:
  prometheus:
    image: prom/prometheus:latest        # Prometheus
    container_name: prometheus
    restart: unless-stopped
    ports:
      - "9090:9090"                      # Web 界面
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml  # 配置
      - ./alert_rules.yml:/etc/prometheus/alert_rules.yml  # 告警规则
      - prometheus_data:/prometheus      # 数据持久化
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.retention.time=30d'  # 数据保留 30 天

  node-exporter:
    image: prom/node-exporter:latest     # 服务器指标采集
    container_name: node-exporter
    restart: unless-stopped
    ports:
      - "9100:9100"
    pid: host                            # 获取宿主机进程信息

  alertmanager:
    image: prom/alertmanager:latest      # 告警管理
    container_name: alertmanager
    restart: unless-stopped
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml

volumes:
  prometheus_data:

基本使用

访问 Web 界面

# 浏览器打开:http://localhost:9090
# 
# 主要页面:
# - Graph:查询和图表(输入 PromQL)
# - Alerts:告警规则和状态
# - Status → Targets:查看所有采集目标的状态
# - Status → Configuration:查看当前配置

PromQL 基础查询

# === 基本查询 ===
up                                     # 目标是否在线(1=在线,0=离线)
node_cpu_seconds_total                 # CPU 时间总量(原始计数器)

# === 常用函数 ===
rate(metric[5m])                       # 每秒变化率(5分钟窗口)
irate(metric[5m])                      # 瞬时变化率
increase(metric[1h])                   # 1小时内的增量
avg(metric)                            # 平均值
sum(metric)                            # 总和
max(metric)                            # 最大值
min(metric)                            # 最小值

# === 实用查询示例 ===
# CPU 使用率(%)
100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# 内存使用率(%)
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100

# 磁盘使用率(%)
(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100

# 网络流入速率(MB/s)
rate(node_network_receive_bytes_total{device="eth0"}[5m]) / 1024 / 1024

# HTTP 请求速率
rate(http_requests_total[5m])

# HTTP 错误率(%)
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100

# P99 延迟
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

配置告警规则

# alert_rules.yml
groups:
  - name: 服务器告警                    # 告警组名
    rules:
      # 实例宕机告警
      - alert: InstanceDown            # 告警名
        expr: up == 0                  # 触发条件(目标离线)
        for: 5m                        # 持续 5 分钟才触发
        labels:
          severity: critical           # 严重级别
        annotations:
          summary: "实例 {{ $labels.instance }} 已宕机"
          description: "{{ $labels.instance }} 已离线超过 5 分钟"

      # CPU 高负载告警
      - alert: HighCPU
        expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "CPU 使用率超过 90%"
          description: "{{ $labels.instance }} CPU 使用率 {{ $value }}%"

      # 磁盘空间不足
      - alert: DiskSpaceLow
        expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) < 0.15
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "磁盘空间不足 15%"

Alertmanager 通知配置

# alertmanager.yml
route:
  receiver: 'default'                  # 默认接收者
  group_wait: 30s                      # 等待 30 秒后发送分组告警
  group_interval: 5m                   # 同组告警间隔
  repeat_interval: 4h                  # 重复告警间隔

receivers:
  - name: 'default'
    webhook_configs:                   # Webhook 通知
      - url: 'http://your-webhook-url'
    # email_configs:                   # 邮件通知
    #   - to: 'admin@example.com'
    #     from: 'prometheus@example.com'
    #     smarthost: 'smtp.gmail.com:587'

高级用法

服务发现(自动发现目标)

# prometheus.yml — Docker 服务发现
scrape_configs:
  - job_name: 'docker'
    docker_sd_configs:                 # Docker 容器自动发现
      - host: unix:///var/run/docker.sock
    relabel_configs:                   # 标签重写规则
      - source_labels: [__meta_docker_container_name]
        target_label: container        # 容器名作为标签

  # Kubernetes 服务发现
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod

指标类型详解

# 1. Counter(计数器)— 只增不减
# 例:http_requests_total(总请求数)
# 用 rate() 计算速率:rate(http_requests_total[5m])

# 2. Gauge(仪表盘)— 可增可减
# 例:node_memory_MemAvailable_bytes(可用内存)
# 直接查询即可

# 3. Histogram(直方图)— 分布统计
# 例:http_request_duration_seconds_bucket(请求延迟分布)
# 用 histogram_quantile() 计算分位数

# 4. Summary(摘要)— 类似 Histogram
# 客户端计算分位数,适合跨实例聚合

远程存储(长期存储)

# prometheus.yml — 远程写入配置
remote_write:
  - url: "http://mimir:9009/api/v1/push"  # 写到 Grafana Mimir
    # 或写到 Thanos / VictoriaMetrics 等

常见报错

报错信息原因解决方案
target is down目标服务未暴露 /metrics安装对应 Exporter 并检查端口
out of order sample时间戳乱序检查目标服务器时间同步
TSDB corruption存储数据损坏删除损坏的 WAL 文件重启
too many time series指标数量爆炸使用 relabel 过滤不需要的指标
query timeout查询太复杂或数据量太大优化 PromQL 或增加超时时间
scrape error采集失败检查网络和目标服务状态

速查表

# === 常用 Exporter ===
node-exporter      9100  # 服务器指标
cadvisor           8080  # Docker 容器指标
mysqld-exporter    9104  # MySQL
postgres-exporter  9187  # PostgreSQL
redis-exporter     9121  # Redis
blackbox-exporter  9115  # HTTP/TCP 探测
nginx-exporter     9113  # Nginx

# === PromQL 速查 ===
rate(m[5m])                 # 速率
increase(m[1h])             # 增量
avg by(label)(m)            # 按标签平均
sum without(instance)(m)    # 排除标签求和
topk(5, m)                  # 前5名
bottomk(5, m)               # 后5名
count(m > 90)               # 大于90的数量
absent(m)                   # 指标不存在则返回1

# === 默认端口 ===
# 9090 → Prometheus Web UI
# 9093 → Alertmanager
# 9100 → Node Exporter

同类对比

特性PrometheusZabbixInfluxDBDatadog
采集模式PullPush+PullPushAgent
查询语言PromQL自有InfluxQL/Flux自有
存储本地TSDBDBTSDB云端
云原生支持原生插件基础原生
学习曲线中等中等
价格免费免费付费版按量付费
适合场景K8s/微服务传统运维IoT/时序全栈SaaS

选型建议:Kubernetes 和云原生环境首选 Prometheus(标配);传统服务器监控选 Zabbix;时序数据分析选 InfluxDB。Prometheus + Grafana 是最经典的开源监控组合。